#include "ostree-tls-cert-interaction.h"
#endif
#include "ostree.h"
+#include "ostree-repo-private.h"
#include "otutil.h"
typedef enum {
GObject parent_instance;
int tmpdir_dfd;
+ char *tmpdir_name;
+ GLnxLockFile tmpdir_lock;
+ int base_tmpdir_dfd;
GTlsCertificate *client_cert;
self = OSTREE_FETCHER (object);
+ if (self->tmpdir_dfd != -1)
+ close (self->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 (self->tmpdir_name);
+ glnx_release_lock_file (&self->tmpdir_lock);
+
g_clear_object (&self->session);
g_clear_object (&self->client_cert);
{
gint max_conns;
const char *http_proxy;
+ GLnxLockFile empty_lockfile = GLNX_LOCK_FILE_INIT;
g_queue_init (&self->pending_queue);
self->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
self->output_stream_set = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref);
self->outstanding = g_hash_table_new_full (NULL, NULL, NULL, NULL);
+
+ self->tmpdir_dfd = -1;
+ self->tmpdir_lock = empty_lockfile;
+
}
OstreeFetcher *
_ostree_fetcher_new (int tmpdir_dfd,
- OstreeFetcherConfigFlags flags)
+ OstreeFetcherConfigFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
OstreeFetcher *self = (OstreeFetcher*)g_object_new (OSTREE_TYPE_FETCHER, NULL);
- self->tmpdir_dfd = tmpdir_dfd;
+ if (!_ostree_repo_allocate_tmpdir (tmpdir_dfd,
+ "fetcher-",
+ &self->tmpdir_name,
+ &self->tmpdir_dfd,
+ &self->tmpdir_lock,
+ NULL,
+ cancellable, error))
+ return NULL;
+
+ self->base_tmpdir_dfd = tmpdir_dfd;
if ((flags & OSTREE_FETCHER_FLAGS_TLS_PERMISSIVE) > 0)
g_object_set ((GObject*)self->session, "ssl-strict", FALSE, NULL);
-
+
return self;
}
GAsyncResult *result,
gpointer user_data)
{
+ OstreeFetcher *fetcher = (OstreeFetcher *)object;
FetchObjectData *fetch_data = user_data;
OtPullData *pull_data = fetch_data->pull_data;
GError *local_error = NULL;
const char *checksum;
OstreeObjectType objtype;
- temp_path = _ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error);
+ temp_path = _ostree_fetcher_request_uri_with_partial_finish (fetcher, result, error);
if (!temp_path)
goto out;
if (!have_object)
{
if (!_ostree_repo_commit_loose_final (pull_data->repo, checksum, OSTREE_OBJECT_TYPE_FILE,
- pull_data->tmpdir_dfd, temp_path,
+ _ostree_fetcher_get_dfd (fetcher), temp_path,
cancellable, error))
goto out;
}
else
{
/* Non-mirroring path */
-
- if (!ostree_content_file_parse_at (TRUE, pull_data->tmpdir_dfd, temp_path, FALSE,
+
+ if (!ostree_content_file_parse_at (TRUE, _ostree_fetcher_get_dfd (fetcher),
+ temp_path, FALSE,
&file_in, &file_info, &xattrs,
cancellable, error))
{
/* If it appears corrupted, delete it */
- (void) unlinkat (pull_data->tmpdir_dfd, temp_path, 0);
+ (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
goto out;
}
* a reference to the fd. If we fail to write later, then
* the temp space will be cleaned up.
*/
- (void) unlinkat (pull_data->tmpdir_dfd, temp_path, 0);
-
+ (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
+
if (!ostree_raw_file_to_content_stream (file_in, file_info, xattrs,
&object_input, &length,
cancellable, error))
GAsyncResult *result,
gpointer user_data)
{
+ OstreeFetcher *fetcher = (OstreeFetcher *)object;
FetchObjectData *fetch_data = user_data;
OtPullData *pull_data = fetch_data->pull_data;
g_autoptr(GVariant) metadata = NULL;
g_debug ("fetch of %s%s complete", ostree_object_to_string (checksum, objtype),
fetch_data->is_detached_meta ? " (detached)" : "");
- temp_path = _ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error);
+ temp_path = _ostree_fetcher_request_uri_with_partial_finish (fetcher, result, error);
if (!temp_path)
{
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
if (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT)
goto out;
- fd = openat (pull_data->tmpdir_dfd, temp_path, O_RDONLY | O_CLOEXEC);
+ fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
{
gs_set_error_from_errno (error, errno);
goto out;
/* Now delete it, see comment in corresponding content fetch path */
- (void) unlinkat (pull_data->tmpdir_dfd, temp_path, 0);
+ (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata,
pull_data->cancellable, error))
FALSE, &metadata, error))
goto out;
- (void) unlinkat (pull_data->tmpdir_dfd, temp_path, 0);
+ (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
/* Write the commitpartial file now while we're still fetching data */
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
GAsyncResult *result,
gpointer user_data)
{
+ OstreeFetcher *fetcher = (OstreeFetcher *)object;
FetchStaticDeltaData *fetch_data = user_data;
OtPullData *pull_data = fetch_data->pull_data;
g_autoptr(GVariant) metadata = NULL;
g_debug ("fetch static delta part %s complete", fetch_data->expected_checksum);
- temp_path = _ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error);
+ temp_path = _ostree_fetcher_request_uri_with_partial_finish (fetcher, result, error);
if (!temp_path)
goto out;
- fd = openat (pull_data->tmpdir_dfd, temp_path, O_RDONLY | O_CLOEXEC);
+ fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
{
gs_set_error_from_errno (error, errno);
* or error, the file will be gone. This is particularly
* important if say we hit e.g. ENOSPC.
*/
- (void) unlinkat (pull_data->tmpdir_dfd, temp_path, 0);
+ (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
_ostree_static_delta_part_execute_async (pull_data->repo,
fetch_data->objects,