Skip to content

Commit

Permalink
prune: support .payload-link files
Browse files Browse the repository at this point in the history
Prune payload-links to files that are not present in the repository.

A .payload-link is stored only once, even if there are two objects
with different checksums but same payload.  In the case prune deletes
the file referred by the payload-link, the other file won't have any
.payload-reference left.  A better algorithm to deal with this case
would be to delete every .payload-link file and then recreate them all
for the objects that are left in the repository at the expense of
calculating the checksum for each object in repository.

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Feb 14, 2018
1 parent 5c1a2a0 commit 79df3f3
Showing 1 changed file with 31 additions and 3 deletions.
34 changes: 31 additions & 3 deletions src/libostree/ostree-repo-prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,43 @@ maybe_prune_loose_object (OtPruneData *data,
GCancellable *cancellable,
GError **error)
{
gboolean reachable = FALSE;
g_autoptr(GVariant) key = NULL;

key = ostree_object_name_serialize (checksum, objtype);

if (!g_hash_table_lookup_extended (data->reachable, key, NULL, NULL))
if (g_hash_table_lookup_extended (data->reachable, key, NULL, NULL))
reachable = TRUE;
else
{
g_debug ("Pruning unneeded object %s.%s", checksum,
ostree_object_type_to_string (objtype));
if (!(flags & OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE))
{
guint64 storage_size = 0;

if (objtype == OSTREE_OBJECT_TYPE_PAYLOAD_LINK)
{
char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
char target_checksum[OSTREE_SHA256_STRING_LEN+1];

_ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, data->repo->mode);
if (readlinkat (data->repo->objects_dir_fd, loose_path_buf, target_checksum, sizeof (target_checksum)) < 0)
return glnx_throw_errno (error);

g_autoptr(GVariant) target_key = ostree_object_name_serialize (target_checksum, OSTREE_OBJECT_TYPE_FILE);

if (g_hash_table_lookup_extended (data->reachable, target_key, NULL, NULL))
{
if (!ostree_repo_query_object_storage_size (data->repo, OSTREE_OBJECT_TYPE_FILE, target_checksum,
&storage_size, cancellable, error))
return FALSE;

reachable = storage_size >= data->repo->payload_link_threshold;
if (reachable)
goto exit;
}
}
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{
if (!ostree_repo_mark_commit_partial (data->repo, checksum, FALSE, error))
Expand All @@ -79,7 +104,9 @@ maybe_prune_loose_object (OtPruneData *data,
else
data->n_unreachable_content++;
}
else

exit:
if (reachable)
{
g_debug ("Keeping needed object %s.%s", checksum,
ostree_object_type_to_string (objtype));
Expand Down Expand Up @@ -233,6 +260,7 @@ repo_prune_internal (OstreeRepo *self,
g_autoptr(GHashTable) reachable_owned = g_hash_table_ref (options->reachable);
data.reachable = reachable_owned;


GLNX_HASH_TABLE_FOREACH_KV (objects, GVariant*, serialized_key, GVariant*, objdata)
{
const char *checksum;
Expand Down Expand Up @@ -283,7 +311,7 @@ repo_prune_internal (OstreeRepo *self,
* of traversing all commits, only refs will be used. Particularly
* when combined with @depth, this is a convenient way to delete
* history from the repository.
*
*
* Use the %OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE to just determine
* statistics on objects that would be deleted, without actually
* deleting them.
Expand Down

0 comments on commit 79df3f3

Please sign in to comment.