From 08476ce2544c25c158895c647ed54a29152a7b0b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Feb 2015 13:04:52 -0500 Subject: [PATCH] deltas: Prune deltas when the corresponding "to" commit vanishes We want prune to actually give you back disk space when using deltas. --- src/libostree/ostree-core-private.h | 7 ++- src/libostree/ostree-core.c | 52 +++++++++++-------- src/libostree/ostree-repo-prune.c | 44 ++++++++++++++++ src/libostree/ostree-repo-pull.c | 3 +- .../ostree-repo-static-delta-compilation.c | 2 +- src/libostree/ostree-repo.c | 2 +- tests/test-delta.sh | 2 + 7 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h index 402cc5d7..8d6cb93b 100644 --- a/src/libostree/ostree-core-private.h +++ b/src/libostree/ostree-core-private.h @@ -96,7 +96,12 @@ _ostree_get_relative_object_path (const char *checksum, char * _ostree_get_relative_static_delta_path (const char *from, - const char *to); + const char *to, + const char *target); + +char * +_ostree_get_relative_static_delta_superblock_path (const char *from, + const char *to); char * _ostree_get_relative_static_delta_detachedmeta_path (const char *from, diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 570e8199..6a72251e 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -1425,15 +1425,15 @@ _ostree_get_relative_object_path (const char *checksum, return g_string_free (path, FALSE); } -static char * -get_delta_path (const char *from, - const char *to, - const char *target) +char * +_ostree_get_relative_static_delta_path (const char *from, + const char *to, + const char *target) { - char prefix[3]; guint8 csum_to[32]; char to_b64[44]; guint8 csum_to_copy[32]; + GString *ret = g_string_new ("deltas/"); ostree_checksum_inplace_to_bytes (to, csum_to); ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64); @@ -1441,14 +1441,7 @@ get_delta_path (const char *from, g_assert (memcmp (csum_to, csum_to_copy, 32) == 0); - if (from == NULL) - { - prefix[0] = to_b64[0]; - prefix[1] = to_b64[1]; - prefix[2] = '\0'; - return g_strconcat ("deltas/", prefix, "/", ((char*)to_b64)+2, "/", target, NULL); - } - else + if (from != NULL) { guint8 csum_from[32]; char from_b64[44]; @@ -1456,25 +1449,40 @@ get_delta_path (const char *from, ostree_checksum_inplace_to_bytes (from, csum_from); ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64); - prefix[0] = from_b64[0]; - prefix[1] = from_b64[1]; - prefix[2] = '\0'; - return g_strconcat ("deltas/", prefix, "/", ((char*)from_b64)+2, "-", to_b64, "/", target, NULL); + g_string_append_c (ret, from_b64[0]); + g_string_append_c (ret, from_b64[1]); + g_string_append_c (ret, '/'); + g_string_append (ret, from_b64 + 2); + g_string_append_c (ret, '-'); } + + g_string_append_c (ret, to_b64[0]); + g_string_append_c (ret, to_b64[1]); + if (from == NULL) + g_string_append_c (ret, '/'); + g_string_append (ret, to_b64 + 2); + + if (target != NULL) + { + g_string_append_c (ret, '/'); + g_string_append (ret, target); + } + + return g_string_free (ret, FALSE); } char * -_ostree_get_relative_static_delta_path (const char *from, - const char *to) +_ostree_get_relative_static_delta_superblock_path (const char *from, + const char *to) { - return get_delta_path (from, to, "superblock"); + return _ostree_get_relative_static_delta_path (from, to, "superblock"); } char * _ostree_get_relative_static_delta_detachedmeta_path (const char *from, const char *to) { - return get_delta_path (from, to, "meta"); + return _ostree_get_relative_static_delta_path (from, to, "meta"); } char * @@ -1483,7 +1491,7 @@ _ostree_get_relative_static_delta_part_path (const char *from, guint i) { gs_free char *partstr = g_strdup_printf ("%u", i); - return get_delta_path (from, to, partstr); + return _ostree_get_relative_static_delta_path (from, to, partstr); } /* diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 05ba43a1..cff2f600 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ostree-core-private.h" #include "ostree-repo-private.h" #include "otutil.h" @@ -212,6 +213,49 @@ ostree_repo_prune (OstreeRepo *self, cancellable, error)) goto out; } + + { gs_unref_ptrarray GPtrArray *deltas = NULL; + guint i; + + if (!ostree_repo_list_static_delta_names (self, &deltas, + cancellable, error)) + goto out; + + for (i = 0; i < deltas->len; i++) + { + const char *deltaname = deltas->pdata[i]; + const char *dash = strchr (deltaname, '-'); + const char *to = NULL; + gboolean have_commit; + gs_free char *from = NULL; + gs_free char *deltadir = NULL; + + if (!dash) + { + to = deltaname; + } + else + { + from = g_strndup (deltaname, dash - deltaname); + to = dash + 1; + } + + if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, + to, &have_commit, + cancellable, error)) + goto out; + + if (have_commit) + continue; + + deltadir = _ostree_get_relative_static_delta_path (from, to, NULL); + + if (!gs_shutil_rm_rf_at (self->repo_dir_fd, deltadir, + cancellable, error)) + goto out; + } + } + ret = TRUE; *out_objects_total = (data.n_reachable_meta + data.n_unreachable_meta + data.n_reachable_content + data.n_unreachable_content); diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index daf61377..5d359672 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1340,7 +1340,8 @@ request_static_delta_superblock_sync (OtPullData *pull_data, { gboolean ret = FALSE; gs_unref_variant GVariant *ret_delta_superblock = NULL; - gs_free char *delta_name = _ostree_get_relative_static_delta_path (from_revision, to_revision); + gs_free char *delta_name = + _ostree_get_relative_static_delta_superblock_path (from_revision, to_revision); gs_unref_bytes GBytes *delta_superblock_data = NULL; gs_unref_bytes GBytes *delta_meta_data = NULL; gs_unref_variant GVariant *delta_superblock = NULL; diff --git a/src/libostree/ostree-repo-static-delta-compilation.c b/src/libostree/ostree-repo-static-delta-compilation.c index 594b432f..62d006ef 100644 --- a/src/libostree/ostree-repo-static-delta-compilation.c +++ b/src/libostree/ostree-repo-static-delta-compilation.c @@ -1122,7 +1122,7 @@ ostree_repo_static_delta_generate (OstreeRepo *self, part_builder->uncompressed_size); } - descriptor_relpath = _ostree_get_relative_static_delta_path (from, to); + descriptor_relpath = _ostree_get_relative_static_delta_superblock_path (from, to); descriptor_path = g_file_resolve_relative_path (self->repodir, descriptor_relpath); descriptor_dir = g_file_get_parent (descriptor_path); diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 7e01bb39..85792d88 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3209,7 +3209,7 @@ ostree_repo_sign_delta (OstreeRepo *self, _ostree_get_relative_static_delta_detachedmeta_path (from_commit, to_commit); detached_metadata_path = g_file_resolve_relative_path (self->repodir, detached_metadata_relpath); - delta_path = _ostree_get_relative_static_delta_path (from_commit, to_commit); + delta_path = _ostree_get_relative_static_delta_superblock_path (from_commit, to_commit); delta_file = g_file_resolve_relative_path (self->repodir, delta_path); delta_data = gs_file_map_readonly (delta_file, cancellable, error); if (!delta_data) diff --git a/tests/test-delta.sh b/tests/test-delta.sh index 988d7ab6..f5bb802c 100755 --- a/tests/test-delta.sh +++ b/tests/test-delta.sh @@ -59,6 +59,8 @@ origrev=$(ostree --repo=repo rev-parse test) ostree --repo=repo static-delta generate --empty --to=${origrev} ostree --repo=repo static-delta list | grep ${origrev} || exit 1 +ostree --repo=repo prune +ostree --repo=repo static-delta list | grep ${origrev} || exit 1 permuteDirectory 1 files ostree --repo=repo commit -b test -s test --tree=dir=files