[ostree] fetcher: Lazily create tmp directory



commit 1f1bfbf711221168f1a3fc6e18cde2929c0ac1d7
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Dec 18 10:50:08 2015 -0500

    fetcher: Lazily create tmp directory
    
    The tmp directory is lazily created for each fetcher instance, since
    it may require superuser permissions and some instances only need
    _ostree_fetcher_request_uri_to_membuf() which keeps everything in
    memory buffers.

 src/libostree/ostree-fetcher.c |   64 ++++++++++++++++++++++-----------------
 src/libostree/ostree-fetcher.h |    4 +--
 src/libostree/ostree-repo.c    |    4 +--
 3 files changed, 38 insertions(+), 34 deletions(-)
---
diff --git a/src/libostree/ostree-fetcher.c b/src/libostree/ostree-fetcher.c
index 8f10308..665286c 100644
--- a/src/libostree/ostree-fetcher.c
+++ b/src/libostree/ostree-fetcher.c
@@ -48,6 +48,10 @@ typedef struct {
   GMainLoop *main_loop;
 
   int tmpdir_dfd;
+  char *tmpdir_name;
+  GLnxLockFile tmpdir_lock;
+  int base_tmpdir_dfd;
+
   int max_outstanding;
 
   /* Queue for libsoup, see bgo#708591 */
@@ -100,10 +104,6 @@ struct OstreeFetcher
 
   OstreeFetcherConfigFlags config_flags;
 
-  char *tmpdir_name;
-  GLnxLockFile tmpdir_lock;
-  int base_tmpdir_dfd;
-
   GThread *session_thread;
   ThreadClosure *thread_closure;
 };
@@ -142,6 +142,14 @@ thread_closure_unref (ThreadClosure *thread_closure)
       if (thread_closure->tmpdir_dfd != -1)
         close (thread_closure->tmpdir_dfd);
 
+      /* Note: We don't remove the tmpdir here, because that would cause
+         us to not reuse it on resume. This happens because we use two
+         fetchers for each pull, so finalizing the first one would remove
+         all the files to be resumed from the previous second one */
+
+      g_free (thread_closure->tmpdir_name);
+      glnx_release_lock_file (&thread_closure->tmpdir_lock);
+
       while (!g_queue_is_empty (&thread_closure->pending_queue))
         g_object_unref (g_queue_pop_head (&thread_closure->pending_queue));
 
@@ -363,6 +371,26 @@ session_thread_request_uri (ThreadClosure *thread_closure,
       struct stat stbuf;
       gboolean exists;
 
+      /* The tmp directory is lazily created for each fetcher instance,
+       * since it may require superuser permissions and some instances
+       * only need _ostree_fetcher_request_uri_to_membuf() which keeps
+       * everything in memory buffers. */
+      if (thread_closure->tmpdir_name == NULL)
+        {
+          if (!_ostree_repo_allocate_tmpdir (thread_closure->base_tmpdir_dfd,
+                                             "fetcher-",
+                                             &thread_closure->tmpdir_name,
+                                             &thread_closure->tmpdir_dfd,
+                                             &thread_closure->tmpdir_lock,
+                                             NULL,
+                                             cancellable,
+                                             &local_error))
+            {
+              g_task_return_error (task, local_error);
+              return;
+            }
+        }
+
       tmpfile = g_compute_checksum_for_string (G_CHECKSUM_SHA256, uristring, strlen (uristring));
 
       if (fstatat (thread_closure->tmpdir_dfd, tmpfile, &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
@@ -484,14 +512,6 @@ _ostree_fetcher_finalize (GObject *object)
   g_clear_pointer (&self->session_thread, g_thread_unref);
   g_clear_pointer (&self->thread_closure, thread_closure_unref);
 
-  /* Note: We don't remove the tmpdir here, because that would cause
-     us to not reuse it on resume. This happens because we use two
-     fetchers for each pull, so finalizing the first one would remove
-     all the files to be resumed from the previous second one */
-
-  g_free (self->tmpdir_name);
-  glnx_release_lock_file (&self->tmpdir_lock);
-
   G_OBJECT_CLASS (_ostree_fetcher_parent_class)->finalize (object);
 }
 
@@ -500,6 +520,7 @@ _ostree_fetcher_constructed (GObject *object)
 {
   OstreeFetcher *self = OSTREE_FETCHER (object);
   g_autoptr(GMainContext) main_context = NULL;
+  GLnxLockFile empty_lockfile = GLNX_LOCK_FILE_INIT;
   const char *http_proxy;
 
   main_context = g_main_context_new ();
@@ -509,6 +530,7 @@ _ostree_fetcher_constructed (GObject *object)
   self->thread_closure->main_context = g_main_context_ref (main_context);
   self->thread_closure->main_loop = g_main_loop_new (main_context, FALSE);
   self->thread_closure->tmpdir_dfd = -1;
+  self->thread_closure->tmpdir_lock = empty_lockfile;
 
   self->thread_closure->outstanding = g_hash_table_new (NULL, NULL);
   self->thread_closure->output_stream_set = g_hash_table_new_full (NULL, NULL,
@@ -568,31 +590,17 @@ _ostree_fetcher_class_init (OstreeFetcherClass *klass)
 static void
 _ostree_fetcher_init (OstreeFetcher *self)
 {
-  GLnxLockFile empty_lockfile = GLNX_LOCK_FILE_INIT;
-
-  self->tmpdir_lock = empty_lockfile;
 }
 
 OstreeFetcher *
 _ostree_fetcher_new (int                      tmpdir_dfd,
-                     OstreeFetcherConfigFlags flags,
-                     GCancellable            *cancellable,
-                     GError                 **error)
+                     OstreeFetcherConfigFlags flags)
 {
   OstreeFetcher *self;
 
   self = g_object_new (OSTREE_TYPE_FETCHER, "config-flags", flags, NULL);
 
-  if (!_ostree_repo_allocate_tmpdir (tmpdir_dfd,
-                                     "fetcher-",
-                                     &self->tmpdir_name,
-                                     &self->thread_closure->tmpdir_dfd,
-                                     &self->tmpdir_lock,
-                                     NULL,
-                                     cancellable, error))
-    return NULL;
-
-  self->base_tmpdir_dfd = tmpdir_dfd;
+  self->thread_closure->base_tmpdir_dfd = tmpdir_dfd;
 
   return self;
 }
diff --git a/src/libostree/ostree-fetcher.h b/src/libostree/ostree-fetcher.h
index f9c0e04..60a1375 100644
--- a/src/libostree/ostree-fetcher.h
+++ b/src/libostree/ostree-fetcher.h
@@ -55,9 +55,7 @@ typedef enum {
 GType   _ostree_fetcher_get_type (void) G_GNUC_CONST;
 
 OstreeFetcher *_ostree_fetcher_new (int                      tmpdir_dfd,
-                                    OstreeFetcherConfigFlags flags,
-                                    GCancellable            *cancellable,
-                                    GError                 **error);
+                                    OstreeFetcherConfigFlags flags);
 
 int  _ostree_fetcher_get_dfd (OstreeFetcher *fetcher);
 
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index f9cd5cc..415421a 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -419,9 +419,7 @@ _ostree_repo_remote_new_fetcher (OstreeRepo  *self,
   if (tls_permissive)
     fetcher_flags |= OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE;
 
-  fetcher = _ostree_fetcher_new (self->tmp_dir_fd, fetcher_flags, NULL, error);
-  if (fetcher == NULL)
-    goto out;
+  fetcher = _ostree_fetcher_new (self->tmp_dir_fd, fetcher_flags);
 
   {
     g_autofree char *tls_client_cert_path = NULL;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]