diff --git a/src/app/rpmostree-container-builtins.c b/src/app/rpmostree-container-builtins.c index 6ecf54d1..9e8b7322 100644 --- a/src/app/rpmostree-container-builtins.c +++ b/src/app/rpmostree-container-builtins.c @@ -213,24 +213,16 @@ download_rpms_and_assemble_commit (ROContainerContext *rocctx, if (!rpmostree_context_import (rocctx->ctx, cancellable, error)) return FALSE; - g_auto(GLnxTmpDir) tmpdir = { 0, }; - if (!glnx_mkdtempat (rocctx->userroot_dfd, "tmp/rpmostree-commit-XXXXXX", 0755, - &tmpdir, error)) + if (!rpmostree_context_assemble (rocctx->ctx, cancellable, error)) return FALSE; - g_autoptr(OstreeRepoDevInoCache) devino_cache = ostree_repo_devino_cache_new (); - rpmostree_context_set_devino_cache (rocctx->ctx, devino_cache); - if (!rpmostree_context_assemble_tmprootfs (rocctx->ctx, tmpdir.fd, - cancellable, error)) - return FALSE; - - if (!rpmostree_rootfs_postprocess_common (tmpdir.fd, cancellable, error)) + if (!rpmostree_rootfs_postprocess_common (rpmostree_context_get_tmprootfs_dfd (rocctx->ctx), + cancellable, error)) return FALSE; g_autofree char *ret_commit = NULL; - if (!rpmostree_context_commit_tmprootfs (rocctx->ctx, tmpdir.fd, - NULL, RPMOSTREE_ASSEMBLE_TYPE_SERVER_BASE, - &ret_commit, cancellable, error)) + if (!rpmostree_context_commit (rocctx->ctx, NULL, RPMOSTREE_ASSEMBLE_TYPE_SERVER_BASE, + &ret_commit, cancellable, error)) return FALSE; *out_commit = g_steal_pointer (&ret_commit); diff --git a/src/daemon/rpmostree-sysroot-upgrader.c b/src/daemon/rpmostree-sysroot-upgrader.c index 31c76ad0..f12df54a 100644 --- a/src/daemon/rpmostree-sysroot-upgrader.c +++ b/src/daemon/rpmostree-sysroot-upgrader.c @@ -895,6 +895,9 @@ perform_local_assembly (RpmOstreeSysrootUpgrader *self, if (self->layering_type == RPMOSTREE_SYSROOT_UPGRADER_LAYERING_NONE) return TRUE; + rpmostree_context_set_devino_cache (self->ctx, self->devino_cache); + rpmostree_context_set_tmprootfs_dfd (self->ctx, self->tmprootfs_dfd); + if (self->layering_type == RPMOSTREE_SYSROOT_UPGRADER_LAYERING_RPMMD_REPOS) { if (!rpmostree_context_relabel (self->ctx, cancellable, error)) @@ -902,11 +905,8 @@ perform_local_assembly (RpmOstreeSysrootUpgrader *self, g_clear_pointer (&self->final_revision, g_free); - rpmostree_context_set_devino_cache (self->ctx, self->devino_cache); - /* --- override/overlay and commit --- */ - if (!rpmostree_context_assemble_tmprootfs (self->ctx, self->tmprootfs_dfd, - cancellable, error)) + if (!rpmostree_context_assemble (self->ctx, cancellable, error)) return FALSE; } @@ -948,11 +948,9 @@ perform_local_assembly (RpmOstreeSysrootUpgrader *self, rpmostree_output_task_end ("done"); } - if (!rpmostree_context_commit_tmprootfs (self->ctx, self->tmprootfs_dfd, - self->base_revision, - RPMOSTREE_ASSEMBLE_TYPE_CLIENT_LAYERING, - &self->final_revision, - cancellable, error)) + if (!rpmostree_context_commit (self->ctx, self->base_revision, + RPMOSTREE_ASSEMBLE_TYPE_CLIENT_LAYERING, + &self->final_revision, cancellable, error)) return FALSE; /* Ensure we aren't holding any references to the tmpdir now that we're done; diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c index 7ef7ac41..cb4563fe 100644 --- a/src/libpriv/rpmostree-core.c +++ b/src/libpriv/rpmostree-core.c @@ -260,6 +260,9 @@ struct _RpmOstreeContext { GHashTable *pkgs_to_replace; /* new gv_nevra --> old gv_nevra */ GLnxTmpDir tmpdir; + + int tmprootfs_dfd; /* Borrowed */ + GLnxTmpDir repo_tmpdir; /* Used to assemble+commit if no base rootfs provided */ }; G_DEFINE_TYPE (RpmOstreeContext, rpmostree_context, G_TYPE_OBJECT) @@ -288,6 +291,7 @@ rpmostree_context_finalize (GObject *object) g_clear_pointer (&rctx->pkgs_to_replace, g_hash_table_unref); (void)glnx_tmpdir_delete (&rctx->tmpdir, NULL, NULL); + (void)glnx_tmpdir_delete (&rctx->repo_tmpdir, NULL, NULL); G_OBJECT_CLASS (rpmostree_context_parent_class)->finalize (object); } @@ -302,6 +306,7 @@ rpmostree_context_class_init (RpmOstreeContextClass *klass) static void rpmostree_context_init (RpmOstreeContext *self) { + self->tmprootfs_dfd = -1; } static void @@ -2988,12 +2993,42 @@ run_all_transfiletriggers (RpmOstreeContext *self, return TRUE; } -gboolean -rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self, - int tmprootfs_dfd, - GCancellable *cancellable, - GError **error) +/* Set the root directory fd used for assemble(); used + * by the sysroot upgrader for the base tree. This is optional; + * assemble() will use a tmpdir if not provided. + */ +void +rpmostree_context_set_tmprootfs_dfd (RpmOstreeContext *self, + int dfd) { + g_assert_cmpint (self->tmprootfs_dfd, ==, -1); + self->tmprootfs_dfd = dfd; +} + +int +rpmostree_context_get_tmprootfs_dfd (RpmOstreeContext *self) +{ + return self->tmprootfs_dfd; +} + +gboolean +rpmostree_context_assemble (RpmOstreeContext *self, + GCancellable *cancellable, + GError **error) +{ + /* Synthesize a tmpdir if we weren't provided a base */ + if (self->tmprootfs_dfd == -1) + { + g_assert (!self->repo_tmpdir.initialized); + int repo_dfd = ostree_repo_get_dfd (self->ostreerepo); /* Borrowed */ + if (!glnx_mkdtempat (repo_dfd, "tmp/rpmostree-assemble-XXXXXX", 0700, + &self->repo_tmpdir, error)) + return FALSE; + self->tmprootfs_dfd = self->repo_tmpdir.fd; + } + + int tmprootfs_dfd = self->tmprootfs_dfd; /* Alias to avoid bigger diff */ + DnfContext *hifctx = self->hifctx; TransactionData tdata = { 0, NULL }; g_autoptr(GHashTable) pkg_to_ostree_commit = @@ -3411,13 +3446,12 @@ rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self, } gboolean -rpmostree_context_commit_tmprootfs (RpmOstreeContext *self, - int tmprootfs_dfd, - const char *parent, - RpmOstreeAssembleType assemble_type, - char **out_commit, - GCancellable *cancellable, - GError **error) +rpmostree_context_commit (RpmOstreeContext *self, + const char *parent, + RpmOstreeAssembleType assemble_type, + char **out_commit, + GCancellable *cancellable, + GError **error) { g_autoptr(OstreeRepoCommitModifier) commit_modifier = NULL; g_autofree char *ret_commit_checksum = NULL; @@ -3532,7 +3566,7 @@ rpmostree_context_commit_tmprootfs (RpmOstreeContext *self, if (self->sepolicy) { g_autoptr(OstreeSePolicy) final_sepolicy = NULL; - if (!rpmostree_prepare_rootfs_get_sepolicy (tmprootfs_dfd, &final_sepolicy, + if (!rpmostree_prepare_rootfs_get_sepolicy (self->tmprootfs_dfd, &final_sepolicy, cancellable, error)) return FALSE; @@ -3543,7 +3577,7 @@ rpmostree_context_commit_tmprootfs (RpmOstreeContext *self, mtree = ostree_mutable_tree_new (); - if (!ostree_repo_write_dfd_to_mtree (self->ostreerepo, tmprootfs_dfd, ".", + if (!ostree_repo_write_dfd_to_mtree (self->ostreerepo, self->tmprootfs_dfd, ".", mtree, commit_modifier, cancellable, error)) return FALSE; @@ -3602,6 +3636,10 @@ rpmostree_context_commit_tmprootfs (RpmOstreeContext *self, rpmostree_output_task_end ("done"); + self->tmprootfs_dfd = -1; + if (!glnx_tmpdir_delete (&self->repo_tmpdir, cancellable, error)) + return FALSE; + if (out_commit) *out_commit = g_steal_pointer (&ret_commit_checksum); return TRUE; diff --git a/src/libpriv/rpmostree-core.h b/src/libpriv/rpmostree-core.h index 77d8ff1d..a3f99f23 100644 --- a/src/libpriv/rpmostree-core.h +++ b/src/libpriv/rpmostree-core.h @@ -146,16 +146,18 @@ typedef enum { RPMOSTREE_ASSEMBLE_TYPE_CLIENT_LAYERING } RpmOstreeAssembleType; +void rpmostree_context_set_tmprootfs_dfd (RpmOstreeContext *self, + int dfd); +int rpmostree_context_get_tmprootfs_dfd (RpmOstreeContext *self); + /* NB: tmprootfs_dfd is allowed to have pre-existing data */ /* devino_cache can be NULL if no previous cache established */ -gboolean rpmostree_context_assemble_tmprootfs (RpmOstreeContext *self, - int tmprootfs_dfd, - GCancellable *cancellable, - GError **error); -gboolean rpmostree_context_commit_tmprootfs (RpmOstreeContext *self, - int tmprootfs_dfd, - const char *parent, - RpmOstreeAssembleType assemble_type, - char **out_commit, - GCancellable *cancellable, - GError **error); +gboolean rpmostree_context_assemble (RpmOstreeContext *self, + GCancellable *cancellable, + GError **error); +gboolean rpmostree_context_commit (RpmOstreeContext *self, + const char *parent, + RpmOstreeAssembleType assemble_type, + char **out_commit, + GCancellable *cancellable, + GError **error);