Skip to content

Commit

Permalink
fetcher: Always open tmpfiles in repo (except on FUSE)
Browse files Browse the repository at this point in the history
This reverts commit 4e61e6f
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
ostreedev#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: ostreedev#2571
  • Loading branch information
cgwalters committed Jun 29, 2023
1 parent 8999d41 commit 6364b03
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 21 deletions.
21 changes: 14 additions & 7 deletions src/libostree/ostree-fetcher-curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#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),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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 */
Expand Down
18 changes: 15 additions & 3 deletions src/libostree/ostree-fetcher-soup.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#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>
Expand Down Expand Up @@ -59,6 +60,7 @@ typedef struct

char *remote_name;
int base_tmpdir_dfd;
bool force_anonymous;

GVariant *extra_headers;
gboolean transfer_gzip;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
Expand Down
16 changes: 14 additions & 2 deletions src/libostree/ostree-fetcher-soup3.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct OstreeFetcher
OstreeFetcherConfigFlags config_flags;
char *remote_name;
int tmpdir_dfd;
bool force_anonymous;

GHashTable *sessions; /* (element-type GMainContext SoupSession ) */
GProxyResolver *proxy_resolver;
Expand Down Expand Up @@ -292,6 +293,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 *self)
{
Expand Down Expand Up @@ -448,8 +455,13 @@ 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 (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 (request->fetcher->tmpdir_dfd, &request->tmpf,
&local_error))
{
g_task_return_error (task, local_error);
return;
Expand Down
11 changes: 2 additions & 9 deletions src/libostree/ostree-fetcher-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/libostree/ostree-fetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/libostree/ostree-repo-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/libostree/ostree-repo-pull.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/libostree/ostree-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 6364b03

Please sign in to comment.