summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libostree/ostree-repo-commit.c41
-rw-r--r--src/libostree/ostree-repo-pull.c8
-rw-r--r--src/libostree/ostree-repo-static-delta-core.c17
-rw-r--r--src/libostree/ostree-repo.c48
-rw-r--r--src/libotutil/ot-fs-utils.c60
-rw-r--r--src/libotutil/ot-fs-utils.h5
-rw-r--r--src/libotutil/ot-variant-utils.c94
-rw-r--r--src/libotutil/ot-variant-utils.h24
-rw-r--r--src/ostree/ot-builtin-show.c5
-rw-r--r--src/ostree/ot-builtin-summary.c5
10 files changed, 133 insertions, 174 deletions
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 029dd01b..a9ae4af2 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -2212,26 +2212,29 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self,
char buf[_OSTREE_LOOSE_PATH_MAX];
_ostree_loose_path (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
- g_autoptr(GVariant) ret_metadata = NULL;
- if (self->commit_stagedir.initialized &&
- !ot_util_variant_map_at (self->commit_stagedir.fd, buf,
- G_VARIANT_TYPE ("a{sv}"),
- OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return glnx_prefix_error (error, "Unable to read existing detached metadata");
-
- if (ret_metadata == NULL &&
- !ot_util_variant_map_at (self->objects_dir_fd, buf,
- G_VARIANT_TYPE ("a{sv}"),
- OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return glnx_prefix_error (error, "Unable to read existing detached metadata");
-
- if (ret_metadata == NULL && self->parent_repo)
+ if (self->commit_stagedir.initialized)
+ {
+ glnx_fd_close int fd = -1;
+ if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, buf, &fd, error))
+ return FALSE;
+ if (fd != -1)
+ return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE,
+ out_metadata, error);
+ }
+
+ glnx_fd_close int fd = -1;
+ if (!ot_openat_ignore_enoent (self->objects_dir_fd, buf, &fd, error))
+ return FALSE;
+ if (fd != -1)
+ return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE,
+ out_metadata, error);
+
+ if (self->parent_repo)
return ostree_repo_read_commit_detached_metadata (self->parent_repo,
- checksum,
- out_metadata,
- cancellable,
- error);
- ot_transfer_out_value (out_metadata, &ret_metadata);
+ checksum, out_metadata,
+ cancellable, error);
+ /* Nothing found */
+ *out_metadata = NULL;
return TRUE;
}
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index a404b8a7..57bb1985 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1228,8 +1228,8 @@ meta_fetch_on_complete (GObject *object,
if (fetch_data->is_detached_meta)
{
- if (!ot_util_variant_map_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"),
- FALSE, &metadata, error))
+ if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"),
+ FALSE, &metadata, error))
goto out;
if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata,
@@ -1245,8 +1245,8 @@ meta_fetch_on_complete (GObject *object,
}
else
{
- if (!ot_util_variant_map_fd (fd, 0, ostree_metadata_variant_type (objtype),
- FALSE, &metadata, error))
+ if (!ot_variant_read_fd (fd, 0, ostree_metadata_variant_type (objtype),
+ FALSE, &metadata, error))
goto out;
/* Write the commitpartial file now while we're still fetching data */
diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c
index 85952b6a..e5133a2b 100644
--- a/src/libostree/ostree-repo-static-delta-core.c
+++ b/src/libostree/ostree-repo-static-delta-core.c
@@ -246,8 +246,8 @@ ostree_repo_static_delta_execute_offline (OstreeRepo *self,
return glnx_throw_errno_prefix (error, "openat(%s)", basename);
g_autoptr(GVariant) meta = NULL;
- if (!ot_util_variant_map_fd (meta_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT),
- FALSE, &meta, error))
+ if (!ot_variant_read_fd (meta_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT),
+ FALSE, &meta, error))
return FALSE;
/* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */
@@ -448,8 +448,8 @@ _ostree_static_delta_part_open (GInputStream *part_in,
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))
+ if (!ot_variant_read_fd (part_fd, 1, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
+ trusted, &ret_part, error))
return FALSE;
}
else
@@ -767,9 +767,12 @@ _ostree_repo_static_delta_dump (OstreeRepo *self,
superblock_path = _ostree_get_relative_static_delta_superblock_path (from, to);
- if (!ot_util_variant_map_at (self->repo_dir_fd, superblock_path,
- (GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT,
- OT_VARIANT_MAP_TRUSTED, &delta_superblock, error))
+ glnx_fd_close int superblock_fd = -1;
+ if (!glnx_openat_rdonly (self->repo_dir_fd, superblock_path, TRUE, &superblock_fd, error))
+ return FALSE;
+ if (!ot_variant_read_fd (superblock_fd, 0,
+ (GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT,
+ TRUE, &delta_superblock, error))
return FALSE;
g_print ("Delta: %s\n", delta_id);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 50829152..4357d562 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -2811,7 +2811,6 @@ load_metadata_internal (OstreeRepo *self,
GError **error)
{
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
- struct stat stbuf;
glnx_fd_close int fd = -1;
g_autoptr(GInputStream) ret_stream = NULL;
g_autoptr(GVariant) ret_variant = NULL;
@@ -2853,36 +2852,14 @@ load_metadata_internal (OstreeRepo *self,
if (fd != -1)
{
+ struct stat stbuf;
if (!glnx_fstat (fd, &stbuf, error))
return FALSE;
-
if (out_variant)
{
- /* http://stackoverflow.com/questions/258091/when-should-i-use-mmap-for-file-access */
- if (stbuf.st_size > 16*1024)
- {
- GMappedFile *mfile;
-
- mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
- if (!mfile)
- return FALSE;
- ret_variant = g_variant_new_from_data (ostree_metadata_variant_type (objtype),
- g_mapped_file_get_contents (mfile),
- g_mapped_file_get_length (mfile),
- TRUE,
- (GDestroyNotify) g_mapped_file_unref,
- mfile);
- g_variant_ref_sink (ret_variant);
- }
- else
- {
- g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error);
- if (!data)
- return FALSE;
- ret_variant = g_variant_new_from_bytes (ostree_metadata_variant_type (objtype),
- data, TRUE);
- g_variant_ref_sink (ret_variant);
- }
+ if (!ot_variant_read_fd (fd, 0, ostree_metadata_variant_type (objtype), TRUE,
+ &ret_variant, error))
+ return FALSE;
/* Now, let's put it in the cache */
if (is_dirmeta_cachable)
@@ -4202,15 +4179,24 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GBytes) summary_data = ot_file_mapat_bytes (self->repo_dir_fd, "summary", error);
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (self->repo_dir_fd, "summary", TRUE, &fd, error))
+ return FALSE;
+ g_autoptr(GBytes) summary_data = ot_fd_readall_or_mmap (fd, 0, error);
if (!summary_data)
return FALSE;
+ /* Note that fd is reused below */
+ (void) close (glnx_steal_fd (&fd));
g_autoptr(GVariant) existing_signatures = NULL;
- if (!ot_util_variant_map_at (self->repo_dir_fd, "summary.sig",
- G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING),
- OT_VARIANT_MAP_ALLOW_NOENT, &existing_signatures, error))
+ if (!ot_openat_ignore_enoent (self->repo_dir_fd, "summary.sig", &fd, error))
return FALSE;
+ if (fd != -1)
+ {
+ if (!ot_variant_read_fd (fd, 0, G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING),
+ FALSE, &existing_signatures, error))
+ return FALSE;
+ }
g_autoptr(GVariant) new_metadata = NULL;
for (guint i = 0; key_id[i]; i++)
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index 253de5b3..79ba3cf7 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -22,6 +22,7 @@
#include "ot-fs-utils.h"
#include "libglnx.h"
#include <sys/xattr.h>
+#include <sys/mman.h>
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
@@ -144,22 +145,57 @@ ot_dfd_iter_init_allow_noent (int dfd,
return TRUE;
}
-GBytes *
-ot_file_mapat_bytes (int dfd,
- const char *path,
- GError **error)
-{
- glnx_fd_close int fd = openat (dfd, path, O_RDONLY | O_CLOEXEC);
- g_autoptr(GMappedFile) mfile = NULL;
+typedef struct {
+ gpointer addr;
+ gsize len;
+} MapData;
- if (fd < 0)
- return glnx_null_throw_errno_prefix (error, "openat(%s)", path);
+static void
+map_data_destroy (gpointer data)
+{
+ MapData *mdata = data;
+ (void) munmap (mdata->addr, mdata->len);
+ g_free (mdata);
+}
- mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
- if (!mfile)
+/* Return a newly-allocated GBytes that refers to the contents of the file
+ * starting at offset @start. If the file is large enough, mmap() may be used.
+ */
+GBytes *
+ot_fd_readall_or_mmap (int fd,
+ goffset start,
+ GError **error)
+{
+ struct stat stbuf;
+ if (!glnx_fstat (fd, &stbuf, error))
return FALSE;
- return g_mapped_file_get_bytes (mfile);
+ /* http://stackoverflow.com/questions/258091/when-should-i-use-mmap-for-file-access */
+ if (start > stbuf.st_size)
+ return g_bytes_new_static (NULL, 0);
+ const gsize len = stbuf.st_size - start;
+ if (len > 16*1024)
+ {
+ /* The reason we don't use g_mapped_file_new_from_fd() here
+ * is it doesn't support passing an offset, which is actually
+ * used by the static delta code.
+ */
+ gpointer map = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, start);
+ if (map == (void*)-1)
+ return glnx_null_throw_errno_prefix (error, "mmap");
+
+ MapData *mdata = g_new (MapData, 1);
+ mdata->addr = map;
+ mdata->len = len;
+
+ return g_bytes_new_with_free_func (map, len, map_data_destroy, mdata);
+ }
+
+ /* Fall through to plain read into a malloc buffer */
+ if (lseek (fd, start, SEEK_SET) < 0)
+ return glnx_null_throw_errno_prefix (error, "lseek");
+ /* Not cancellable since this should be small */
+ return glnx_fd_readall_bytes (fd, NULL, error);
}
/* Given an input stream, splice it to an anonymous file (O_TMPFILE).
diff --git a/src/libotutil/ot-fs-utils.h b/src/libotutil/ot-fs-utils.h
index 98fcd6a2..7eb811cd 100644
--- a/src/libotutil/ot-fs-utils.h
+++ b/src/libotutil/ot-fs-utils.h
@@ -85,8 +85,7 @@ ot_map_anonymous_tmpfile_from_content (GInputStream *instream,
GCancellable *cancellable,
GError **error);
-GBytes *ot_file_mapat_bytes (int dfd,
- const char *path,
- GError **error);
+GBytes *ot_fd_readall_or_mmap (int fd, goffset offset,
+ GError **error);
G_END_DECLS
diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c
index d1981c8b..d4ae7d9d 100644
--- a/src/libotutil/ot-variant-utils.c
+++ b/src/libotutil/ot-variant-utils.c
@@ -25,7 +25,6 @@
#include <gio/gfiledescriptorbased.h>
#include <string.h>
-#include <sys/mman.h>
#include "otutil.h"
@@ -85,86 +84,25 @@ ot_util_variant_take_ref (GVariant *variant)
return g_variant_take_ref (variant);
}
+/* Create a GVariant in @out_variant that is backed by
+ * the data from @fd, starting at @start. If the data is
+ * large enough, mmap() may be used. @trusted is used
+ * by the GVariant core; see g_variant_new_from_data().
+ */
gboolean
-ot_util_variant_map_at (int dfd,
- const char *path,
- const GVariantType *type,
- OtVariantMapFlags flags,
- GVariant **out_variant,
- GError **error)
-{
- glnx_fd_close int fd = -1;
- const gboolean trusted = (flags & OT_VARIANT_MAP_TRUSTED) > 0;
-
- fd = openat (dfd, path, O_RDONLY | O_CLOEXEC);
- if (fd < 0)
- {
- if (errno == ENOENT && (flags & OT_VARIANT_MAP_ALLOW_NOENT) > 0)
- {
- *out_variant = NULL;
- return TRUE;
- }
- else
- {
- glnx_set_error_from_errno (error);
- g_prefix_error (error, "Opening %s: ", path);
- return FALSE;
- }
- }
-
- return ot_util_variant_map_fd (fd, 0, type, trusted, out_variant, error);
-}
-
-typedef struct {
- gpointer addr;
- gsize len;
-} VariantMapData;
-
-static void
-variant_map_data_destroy (gpointer data)
-{
- VariantMapData *mdata = data;
- (void) munmap (mdata->addr, mdata->len);
- g_free (mdata);
-}
-
-gboolean
-ot_util_variant_map_fd (int fd,
- goffset start,
- const GVariantType *type,
- gboolean trusted,
- GVariant **out_variant,
- GError **error)
+ot_variant_read_fd (int fd,
+ goffset start,
+ const GVariantType *type,
+ gboolean trusted,
+ GVariant **out_variant,
+ GError **error)
{
- gboolean ret = FALSE;
- gpointer map;
- struct stat stbuf;
- VariantMapData *mdata = NULL;
- gsize len;
-
- if (fstat (fd, &stbuf) != 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- len = stbuf.st_size - start;
- map = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, start);
- if (!map)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- mdata = g_new (VariantMapData, 1);
- mdata->addr = map;
- mdata->len = len;
+ g_autoptr(GBytes) bytes = ot_fd_readall_or_mmap (fd, start, error);
+ if (!bytes)
+ return FALSE;
- ret = TRUE;
- *out_variant = g_variant_ref_sink (g_variant_new_from_data (type, map, len, trusted,
- variant_map_data_destroy, mdata));
- out:
- return ret;
+ *out_variant = g_variant_ref_sink (g_variant_new_from_bytes (type, bytes, trusted));
+ return TRUE;
}
GInputStream *
diff --git a/src/libotutil/ot-variant-utils.h b/src/libotutil/ot-variant-utils.h
index 135ae5d0..379e19ac 100644
--- a/src/libotutil/ot-variant-utils.h
+++ b/src/libotutil/ot-variant-utils.h
@@ -36,24 +36,12 @@ GHashTable *ot_util_variant_asv_to_hash_table (GVariant *variant);
GVariant * ot_util_variant_take_ref (GVariant *variant);
-typedef enum {
- OT_VARIANT_MAP_TRUSTED = (1 << 0),
- OT_VARIANT_MAP_ALLOW_NOENT = (1 << 1)
-} OtVariantMapFlags;
-
-gboolean ot_util_variant_map_at (int dfd,
- const char *path,
- const GVariantType *type,
- OtVariantMapFlags flags,
- GVariant **out_variant,
- GError **error);
-
-gboolean ot_util_variant_map_fd (int fd,
- goffset offset,
- const GVariantType *type,
- gboolean trusted,
- GVariant **out_variant,
- GError **error);
+gboolean ot_variant_read_fd (int fd,
+ goffset offset,
+ const GVariantType *type,
+ gboolean trusted,
+ GVariant **out_variant,
+ GError **error);
GInputStream *ot_variant_read (GVariant *variant);
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index f197d7c3..3ab56eb2 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -58,7 +58,10 @@ do_print_variant_generic (const GVariantType *type,
{
g_autoptr(GVariant) variant = NULL;
- if (!ot_util_variant_map_at (AT_FDCWD, filename, type, TRUE, &variant, error))
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (AT_FDCWD, filename, TRUE, &fd, error))
+ return FALSE;
+ if (!ot_variant_read_fd (fd, 0, type, FALSE, &variant, error))
return FALSE;
ot_dump_variant (variant);
diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c
index abd1f86c..ed9e0b3d 100644
--- a/src/ostree/ot-builtin-summary.c
+++ b/src/ostree/ot-builtin-summary.c
@@ -217,7 +217,10 @@ ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError
if (opt_raw)
flags |= OSTREE_DUMP_RAW;
- summary_data = ot_file_mapat_bytes (repo->repo_dir_fd, "summary", error);
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error))
+ return FALSE;
+ summary_data = ot_fd_readall_or_mmap (fd, 0, error);
if (!summary_data)
return FALSE;