This reverts commit
4e61e6f7d0d6aebd6abcdc455ec53164afe39e8d
and re-instates the fix for ensuring that we download temporary
files into the repository location.
However in order to ensure we don't re-introduce
https://github.com/ostreedev/ostree/issues/2900
we detect the case where we're writing to a FUSE mount
and keep the prior behavior.
I've verified that this works with flatpak.
Note a downside of this is the change needs to be triplicated
across the 3 http backends.
This then again
Closes: https://github.com/ostreedev/ostree/issues/2571
#include <gio/gfiledescriptorbased.h>
#include <gio/gunixoutputstream.h>
#include <glib-unix.h>
+#include <stdbool.h>
/* These macros came from 7.43.0, but we want to check
* for versions a bit earlier than that (to work on CentOS 7),
char *proxy;
struct curl_slist *extra_headers;
int tmpdir_dfd;
+ bool force_anonymous;
char *custom_user_agent;
GMainContext *mainctx;
return fetcher;
}
+void
+_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self)
+{
+ self->force_anonymous = true;
+}
+
static void
destroy_and_unref_source (GSource *source)
{
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 */
#include <gio/gfiledescriptorbased.h>
#include <gio/gio.h>
#include <gio/gunixoutputstream.h>
+#include <stdbool.h>
#define LIBSOUP_USE_UNSTABLE_REQUEST_API
#include <libsoup/soup-request-http.h>
#include <libsoup/soup-requester.h>
char *remote_name;
int base_tmpdir_dfd;
+ bool force_anonymous;
GVariant *extra_headers;
gboolean transfer_gzip;
return self;
}
+void
+_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self)
+{
+ self->thread_closure->force_anonymous = true;
+}
+
int
_ostree_fetcher_get_dfd (OstreeFetcher *fetcher)
{
{
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);
}
#include <gio/gio.h>
#include <gio/gunixoutputstream.h>
#include <libsoup/soup.h>
+#include <stdbool.h>
#include "libglnx.h"
#include "ostree-enumtypes.h"
OstreeFetcherConfigFlags config_flags;
char *remote_name;
int tmpdir_dfd;
+ bool force_anonymous;
GHashTable *sessions; /* (element-type GMainContext SoupSession ) */
GProxyResolver *proxy_resolver;
return self;
}
+void
+_ostree_fetcher_set_force_anonymous_tmpfiles (OstreeFetcher *self)
+{
+ self->force_anonymous = true;
+}
+
int
_ostree_fetcher_get_dfd (OstreeFetcher *self)
{
{
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;
#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;
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);
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;
}
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;
/* 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;