diff options
author | Jonathan Lebon <jonathan@jlebon.com> | 2023-01-30 13:45:50 -0500 |
---|---|---|
committer | Jonathan Lebon <jonathan@jlebon.com> | 2023-01-30 15:08:27 -0500 |
commit | fb63f7aba8887ca616274abad35db30d93f5839e (patch) | |
tree | b8131253012de4bbbefe25c1db75b338d7e3ee27 /src/ostree/ot-builtin-prune.c | |
parent | af505336c2e95820c98fc8e32bce665d5a03c795 (diff) | |
download | ostree-fb63f7aba8887ca616274abad35db30d93f5839e.tar.gz |
ostree/prune: Calculate reachability under exclusive lock
When we calculate the reachability set in `ostree prune`, we do this
without any locking. This means that between the time we build the set
and when we call `ostree_repo_prune_from_reachable`, new content
might've been added. This then causes us to immediately prune that
content since it's not in the now outdated set.
Fix this by calculating the set under an exclusive lock.
I think this is what happened in
https://github.com/fedora-silverblue/issue-tracker/issues/405. While
the pruner was running, the `new-updates-sync` script[1] was importing
content into the repo. The newly imported commits were immediately
deleted by the many `ostree prune --commit-only` calls the pruner does,
breaking the refs.
[1] https://pagure.io/fedora-infra/ansible/blob/35b35127e444/f/roles/bodhi2/backend/files/new-updates-sync#_18
Diffstat (limited to 'src/ostree/ot-builtin-prune.c')
-rw-r--r-- | src/ostree/ot-builtin-prune.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index 73dfe5e5..0b4e8698 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -208,6 +208,15 @@ ostree_builtin_prune (int argc, char **argv, OstreeCommandInvocation *invocation } else { + /* In this branch, we need to compute the reachability set manually. + * While we do this, we can't let new content in since it'll race with + * reachability calculations and we may immediately nuke it. So push an + * exclusive lock now. */ + g_autoptr(OstreeRepoAutoLock) lock = + ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + if (!lock) + return FALSE; + g_autoptr(GHashTable) all_refs = NULL; g_autoptr(GHashTable) reachable = ostree_repo_traverse_new_reachable (); g_autoptr(GHashTable) retain_branch_depth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); |