diff --git a/src/libostree/ostree-fetcher-curl.c b/src/libostree/ostree-fetcher-curl.c index 9d07e5e10c..be88c4ef9f 100644 --- a/src/libostree/ostree-fetcher-curl.c +++ b/src/libostree/ostree-fetcher-curl.c @@ -24,6 +24,7 @@ #include #include #include +#include /* These macros came from 7.43.0, but we want to check * for versions a bit earlier than that (to work on CentOS 7), @@ -76,6 +77,7 @@ struct OstreeFetcher char *proxy; struct curl_slist *extra_headers; int tmpdir_dfd; + bool force_anonymous; char *custom_user_agent; GMainContext *mainctx; @@ -250,6 +252,12 @@ _ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfi return fetcher; } +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->force_anonymous = true; +} + static void destroy_and_unref_source (GSource *source) { @@ -271,13 +279,12 @@ request_get_uri (FetcherRequest *req, GUri *baseuri) static gboolean ensure_tmpfile (FetcherRequest *req, GError **error) { - if (!req->tmpf.initialized) - { - if (!_ostree_fetcher_tmpf_from_flags (req->flags, req->fetcher->tmpdir_dfd, &req->tmpf, - error)) - return FALSE; - } - return TRUE; + if (req->tmpf.initialized) + return TRUE; + if (req->fetcher->force_anonymous) + return glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &req->tmpf, error); + else + return _ostree_fetcher_tmpf (req->fetcher->tmpdir_dfd, &req->tmpf, error); } /* Check for completed transfers, and remove their easy handles */ diff --git a/src/libostree/ostree-fetcher-soup.c b/src/libostree/ostree-fetcher-soup.c index dbba2f002c..629065fffe 100644 --- a/src/libostree/ostree-fetcher-soup.c +++ b/src/libostree/ostree-fetcher-soup.c @@ -25,6 +25,7 @@ #include #include #include +#include #define LIBSOUP_USE_UNSTABLE_REQUEST_API #include #include @@ -59,6 +60,7 @@ typedef struct char *remote_name; int base_tmpdir_dfd; + bool force_anonymous; GVariant *extra_headers; gboolean transfer_gzip; @@ -681,6 +683,12 @@ _ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfi return self; } +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->thread_closure->force_anonymous = true; +} + int _ostree_fetcher_get_dfd (OstreeFetcher *fetcher) { @@ -888,9 +896,13 @@ on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data) { if (!pending->is_membuf) { - if (!_ostree_fetcher_tmpf_from_flags (pending->flags, - pending->thread_closure->base_tmpdir_dfd, - &pending->tmpf, &local_error)) + if (pending->thread_closure->force_anonymous) + { + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &pending->tmpf, &local_error)) + goto out; + } + else if (!_ostree_fetcher_tmpf (pending->thread_closure->base_tmpdir_dfd, &pending->tmpf, + &local_error)) goto out; pending->out_stream = g_unix_output_stream_new (pending->tmpf.fd, FALSE); } diff --git a/src/libostree/ostree-fetcher-soup3.c b/src/libostree/ostree-fetcher-soup3.c index f6ada17abf..380168023f 100644 --- a/src/libostree/ostree-fetcher-soup3.c +++ b/src/libostree/ostree-fetcher-soup3.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "libglnx.h" #include "ostree-enumtypes.h" @@ -72,6 +73,7 @@ struct OstreeFetcher OstreeFetcherConfigFlags config_flags; char *remote_name; int tmpdir_dfd; + bool force_anonymous; GHashTable *sessions; /* (element-type GMainContext SoupSession ) */ GProxyResolver *proxy_resolver; @@ -292,6 +294,12 @@ _ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfi return self; } +void +_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self) +{ + self->force_anonymous = true; +} + int _ostree_fetcher_get_dfd (OstreeFetcher *self) { @@ -448,8 +456,16 @@ on_stream_read (GObject *object, GAsyncResult *result, gpointer user_data) { if (!request->is_membuf) { - if (!_ostree_fetcher_tmpf_from_flags (request->flags, request->fetcher->tmpdir_dfd, - &request->tmpf, &local_error)) + if (request->fetcher->force_anonymous) + { + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &request->tmpf, &local_error)) + { + g_task_return_error (task, local_error); + return; + } + } + else if (!_ostree_fetcher_tmpf (request->fetcher->tmpdir_dfd, &request->tmpf, + &local_error)) { g_task_return_error (task, local_error); return; diff --git a/src/libostree/ostree-fetcher-util.h b/src/libostree/ostree-fetcher-util.h index c3243801ce..97233e1f33 100644 --- a/src/libostree/ostree-fetcher-util.h +++ b/src/libostree/ostree-fetcher-util.h @@ -32,17 +32,10 @@ G_BEGIN_DECLS #define OSTREE_FETCHER_USERAGENT_STRING (PACKAGE_NAME "/" PACKAGE_VERSION) static inline gboolean -_ostree_fetcher_tmpf_from_flags (OstreeFetcherRequestFlags flags, int dfd, GLnxTmpfile *tmpf, - GError **error) +_ostree_fetcher_tmpf (int dfd, GLnxTmpfile *tmpf, GError **error) { - if ((flags & OSTREE_FETCHER_REQUEST_LINKABLE) > 0) - { - if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR | O_CLOEXEC, tmpf, error)) - return FALSE; - } - else if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, tmpf, error)) + if (!glnx_open_tmpfile_linkable_at (dfd, ".", O_RDWR | O_CLOEXEC, tmpf, error)) return FALSE; - if (!glnx_fchmod (tmpf->fd, 0644, error)) return FALSE; return TRUE; diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h index 42ff3a17d3..6a555e0962 100644 --- a/src/libostree/ostree-fetcher.h +++ b/src/libostree/ostree-fetcher.h @@ -88,6 +88,8 @@ GType _ostree_fetcher_get_type (void) G_GNUC_CONST; OstreeFetcher *_ostree_fetcher_new (int tmpdir_dfd, const char *remote_name, OstreeFetcherConfigFlags flags); +void _ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *fetcher); + int _ostree_fetcher_get_dfd (OstreeFetcher *fetcher); void _ostree_fetcher_set_cookie_jar (OstreeFetcher *self, const char *jar_path); diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 6d3f21e61f..d8ca057ddb 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -193,6 +193,7 @@ struct OstreeRepo gboolean inited; gboolean writable; + gboolean is_on_fuse; /* TRUE if the repository is on a FUSE filesystem */ OstreeRepoSysrootKind sysroot_kind; GError *writable_error; gboolean in_transaction; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 6d69d79ee5..2ad9215aa2 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2966,6 +2966,8 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, const char *remote_name, gboo } fetcher = _ostree_fetcher_new (self->tmp_dir_fd, remote_name, fetcher_flags); + if (self->is_on_fuse) + _ostree_fetcher_set_force_anonymous_tmpfiles (fetcher); { g_autofree char *tls_client_cert_path = NULL; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 8633701f40..fc15cb7873 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3426,6 +3426,17 @@ ostree_repo_open (OstreeRepo *self, GCancellable *cancellable, GError **error) /* Note - we don't return this error yet! */ } + { + struct statfs fsstbuf; + if (fstatfs (self->repo_dir_fd, &fsstbuf) < 0) + return glnx_throw_errno_prefix (error, "fstatfs"); +#ifndef FUSE_SUPER_MAGIC +#define FUSE_SUPER_MAGIC 0x65735546 +#endif + self->is_on_fuse = (fsstbuf.f_type == FUSE_SUPER_MAGIC); + g_debug ("using fuse: %d", self->is_on_fuse); + } + if (!glnx_fstat (self->objects_dir_fd, &stbuf, error)) return FALSE; self->owner_uid = stbuf.st_uid;