summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2018-04-30 11:19:17 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-05-24 12:56:11 +0000
commit9131d8a4cc28ea498c2ebc058aac73f70d41841c (patch)
treeb1732a91526f3e39b72d36eb34d26601679d84f6
parent371081d123a9263d8dbdd4dad69c0468e2db427d (diff)
downloadostree-9131d8a4cc28ea498c2ebc058aac73f70d41841c.tar.gz
lib/sysroot: Add wrapper API to prune system repository
The initial motivation for this is that the "staging" code currently didn't rewrite the deployment refs, meaning that the staged commit could be pruned. Hence first, this new API ensures that deployments also hold a strong ref to their commit, without relying on the magical "deployment refs" that we inject. That has always been a weird artifact of the strict layering separation between OstreeSysroot and OstreeRepo. I also plan to change rpm-ostree to start using this API to hold references to base layers for client-side layering; it also today generates various refs. That said, if we still want to support multiple processes writing to a single repo (as happens on EndlessOS today) we still need to write refs; perhaps later we could add a concept of "generators" or something that create refs based on whatever logic? Another minor thing this fixes is that we had a printf inside the library; this propagates the pruned data to the higher level which can log however it likes. Closes: #1566 Approved by: jlebon
-rw-r--r--apidoc/ostree-sections.txt1
-rw-r--r--src/libostree/libostree-devel.sym1
-rw-r--r--src/libostree/ostree-sysroot-cleanup.c95
-rw-r--r--src/libostree/ostree-sysroot.h10
4 files changed, 92 insertions, 15 deletions
diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt
index 6d4a3423..ad1db32c 100644
--- a/apidoc/ostree-sections.txt
+++ b/apidoc/ostree-sections.txt
@@ -509,6 +509,7 @@ ostree_sysroot_get_deployment_dirpath
ostree_sysroot_get_deployment_origin_path
ostree_sysroot_cleanup
ostree_sysroot_prepare_cleanup
+ostree_sysroot_cleanup_prune_repo
ostree_sysroot_repo
ostree_sysroot_get_repo
ostree_sysroot_get_staged_deployment
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym
index eb3b3211..06544bb6 100644
--- a/src/libostree/libostree-devel.sym
+++ b/src/libostree/libostree-devel.sym
@@ -20,6 +20,7 @@
/* Add new symbols here. Release commits should copy this section into -released.sym. */
LIBOSTREE_2018.6 {
ostree_repo_traverse_reachable_refs;
+ ostree_sysroot_cleanup_prune_repo;
} LIBOSTREE_2018.5;
/* Stub section for the stable release *after* this development one; don't
diff --git a/src/libostree/ostree-sysroot-cleanup.c b/src/libostree/ostree-sysroot-cleanup.c
index 1d46222b..7a352e6b 100644
--- a/src/libostree/ostree-sysroot-cleanup.c
+++ b/src/libostree/ostree-sysroot-cleanup.c
@@ -420,25 +420,76 @@ generate_deployment_refs (OstreeSysroot *self,
return TRUE;
}
-static gboolean
-prune_repo (OstreeRepo *repo,
- GCancellable *cancellable,
- GError **error)
+/**
+ * ostree_sysroot_cleanup_prune_repo:
+ * @sysroot: Sysroot
+ * @options: Flags controlling pruning
+ * @out_objects_total: (out): Number of objects found
+ * @out_objects_pruned: (out): Number of objects deleted
+ * @out_pruned_object_size_total: (out): Storage size in bytes of objects deleted
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Prune the system repository. This is a thin wrapper
+ * around ostree_repo_prune_from_reachable(); the primary
+ * addition is that this function automatically gathers
+ * all deployed commits into the reachable set.
+ *
+ * You generally want to at least set the `OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY`
+ * flag in @options. A commit traversal depth of `0` is assumed.
+ *
+ * Locking: exclusive
+ * Since: 2018.6
+ */
+gboolean
+ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot,
+ OstreeRepoPruneOptions *options,
+ gint *out_objects_total,
+ gint *out_objects_pruned,
+ guint64 *out_pruned_object_size_total,
+ GCancellable *cancellable,
+ GError **error)
{
- gint n_objects_total;
- gint n_objects_pruned;
- guint64 freed_space;
- if (!ostree_repo_prune (repo, OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY, 0,
- &n_objects_total, &n_objects_pruned, &freed_space,
- cancellable, error))
+ GLNX_AUTO_PREFIX_ERROR ("Pruning system repository", error);
+ OstreeRepo *repo = ostree_sysroot_repo (sysroot);
+ const guint depth = 0; /* Historical default */
+
+ /* Hold an exclusive lock by default across gathering refs and doing
+ * the prune.
+ */
+ g_autoptr(OstreeRepoAutoLock) lock =
+ _ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error);
+ if (!lock)
return FALSE;
- if (freed_space > 0)
+ /* Ensure reachable has refs, but default to depth 0. This is
+ * what we've always done for the system repo, but perhaps down
+ * the line we could add a depth flag to the repo config or something?
+ */
+ if (!ostree_repo_traverse_reachable_refs (repo, depth, options->reachable, cancellable, error))
+ return FALSE;
+
+ /* Since ostree was created we've been generating "deployment refs" in
+ * generate_deployment_refs() that look like ostree/0/1 etc. to ensure that
+ * anything doing a direct prune won't delete commits backing deployments.
+ * This bit might allow us to eventually drop that behavior, although we'd
+ * have to be very careful to ensure that all software is updated to use
+ * `ostree_sysroot_cleanup_prune_repo()`.
+ */
+ for (guint i = 0; i < sysroot->deployments->len; i++)
{
- g_autofree char *freed_space_str = g_format_size_full (freed_space, 0);
- g_print ("Freed objects: %s\n", freed_space_str);
+ const char *checksum = ostree_deployment_get_csum (sysroot->deployments->pdata[i]);
+ if (!ostree_repo_traverse_commit_union (repo, checksum, depth, options->reachable,
+ cancellable, error))
+ return FALSE;
}
+ if (!ostree_repo_prune_from_reachable (repo, options,
+ out_objects_total, out_objects_pruned,
+ out_pruned_object_size_total,
+ cancellable, error))
+ return FALSE;
+
return TRUE;
}
@@ -501,8 +552,22 @@ _ostree_sysroot_cleanup_internal (OstreeSysroot *self,
if (do_prune_repo)
{
- if (!prune_repo (repo, cancellable, error))
- return glnx_prefix_error (error, "Pruning repo");
+ gint n_objects_total;
+ gint n_objects_pruned;
+ guint64 freed_space;
+ g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable ();
+ OstreeRepoPruneOptions opts = { OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY, reachable };
+ if (!ostree_sysroot_cleanup_prune_repo (self, &opts, &n_objects_total,
+ &n_objects_pruned, &freed_space,
+ cancellable, error))
+ return FALSE;
+
+ /* TODO remove printf in library */
+ if (freed_space > 0)
+ {
+ g_autofree char *freed_space_str = g_format_size_full (freed_space, 0);
+ g_print ("Freed objects: %s\n", freed_space_str);
+ }
}
return TRUE;
diff --git a/src/libostree/ostree-sysroot.h b/src/libostree/ostree-sysroot.h
index 47cbb022..502cd750 100644
--- a/src/libostree/ostree-sysroot.h
+++ b/src/libostree/ostree-sysroot.h
@@ -123,6 +123,16 @@ gboolean ostree_sysroot_prepare_cleanup (OstreeSysroot *self,
GError **error);
_OSTREE_PUBLIC
+gboolean
+ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot,
+ OstreeRepoPruneOptions *options,
+ gint *out_objects_total,
+ gint *out_objects_pruned,
+ guint64 *out_pruned_object_size_total,
+ GCancellable *cancellable,
+ GError **error);
+
+_OSTREE_PUBLIC
gboolean ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
OstreeDeployment *deployment,
GKeyFile *new_origin,