diff --git a/Makefile-libostree.am b/Makefile-libostree.am index dd396974..d40de48d 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -173,9 +173,9 @@ endif # USE_GPGME symbol_files = $(top_srcdir)/src/libostree/libostree-released.sym # Uncomment this include when adding new development symbols. -#if BUILDOPT_IS_DEVEL_BUILD -#symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym -#endif +if BUILDOPT_IS_DEVEL_BUILD +symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym +endif # http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html wl_versionscript_arg = -Wl,--version-script= diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index b09ba6f9..2da1d749 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -319,6 +319,12 @@ ostree_repo_get_min_free_space_bytes ostree_repo_get_config ostree_repo_get_dfd ostree_repo_get_default_repo_finders +OstreeRepoLockType +ostree_repo_lock_pop +ostree_repo_lock_push +OstreeRepoAutoLock +ostree_repo_auto_lock_push +ostree_repo_auto_lock_cleanup ostree_repo_hash ostree_repo_equal ostree_repo_copy_config diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index e3cd14a4..1af5f449 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -22,6 +22,14 @@ - uncomment the include in Makefile-libostree.am */ +LIBOSTREE_2021.3 { +global: + ostree_repo_auto_lock_push; + ostree_repo_auto_lock_cleanup; + ostree_repo_lock_push; + ostree_repo_lock_pop; +} LIBOSTREE_2021.2; + /* Stub section for the stable release *after* this development one; don't * edit this other than to update the year. This is just a copy/paste * source. Replace $LASTSTABLE with the last stable version, and $NEWVERSION diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 1ac53259..dd5cd862 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -1684,8 +1684,8 @@ ostree_repo_prepare_transaction (OstreeRepo *self, memset (&self->txn.stats, 0, sizeof (OstreeRepoTransactionStats)); - self->txn_locked = _ostree_repo_lock_push (self, OSTREE_REPO_LOCK_SHARED, - cancellable, error); + self->txn_locked = ostree_repo_lock_push (self, OSTREE_REPO_LOCK_SHARED, + cancellable, error); if (!self->txn_locked) return FALSE; @@ -2341,7 +2341,7 @@ ostree_repo_commit_transaction (OstreeRepo *self, if (self->txn_locked) { - if (!_ostree_repo_lock_pop (self, cancellable, error)) + if (!ostree_repo_lock_pop (self, cancellable, error)) return FALSE; self->txn_locked = FALSE; } @@ -2399,7 +2399,7 @@ ostree_repo_abort_transaction (OstreeRepo *self, if (self->txn_locked) { - if (!_ostree_repo_lock_pop (self, cancellable, error)) + if (!ostree_repo_lock_pop (self, cancellable, error)) return FALSE; self->txn_locked = FALSE; } diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 14b29c0b..20af1b38 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -506,30 +506,6 @@ _ostree_repo_maybe_regenerate_summary (OstreeRepo *self, GCancellable *cancellable, GError **error); -/* Locking APIs are currently private. - * See https://github.com/ostreedev/ostree/pull/1555 - */ -typedef enum { - OSTREE_REPO_LOCK_SHARED, - OSTREE_REPO_LOCK_EXCLUSIVE -} OstreeRepoLockType; - -gboolean _ostree_repo_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error); -gboolean _ostree_repo_lock_pop (OstreeRepo *self, - GCancellable *cancellable, - GError **error); - -typedef OstreeRepo OstreeRepoAutoLock; - -OstreeRepoAutoLock * _ostree_repo_auto_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error); -void _ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); -G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, _ostree_repo_auto_lock_cleanup) gboolean _ostree_repo_parse_fsverity_config (OstreeRepo *self, GError **error); diff --git a/src/libostree/ostree-repo-prune.c b/src/libostree/ostree-repo-prune.c index 0b953628..c4ce64ab 100644 --- a/src/libostree/ostree-repo-prune.c +++ b/src/libostree/ostree-repo-prune.c @@ -204,7 +204,7 @@ ostree_repo_prune_static_deltas (OstreeRepo *self, const char *commit, GError **error) { g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; @@ -325,7 +325,7 @@ ostree_repo_traverse_reachable_refs (OstreeRepo *self, GError **error) { g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); + ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!lock) return FALSE; @@ -400,7 +400,7 @@ ostree_repo_prune (OstreeRepo *self, GError **error) { g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; @@ -486,7 +486,7 @@ ostree_repo_prune_from_reachable (OstreeRepo *self, GError **error) { g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index e4280af0..d8c33b7c 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -1270,7 +1270,7 @@ ostree_repo_static_delta_reindex (OstreeRepo *repo, /* Protect against parallel prune operation */ g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, cancellable, error); + ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, cancellable, error); if (!lock) return FALSE; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 76b02482..1036a81f 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -444,7 +444,7 @@ pop_repo_lock (OstreeRepo *self, return TRUE; } -/* +/** * ostree_repo_lock_push: * @self: a #OstreeRepo * @lock_type: the type of lock to acquire @@ -470,12 +470,13 @@ pop_repo_lock (OstreeRepo *self, * %TRUE is returned. * * Returns: %TRUE on success, otherwise %FALSE with @error set + * Since: 2021.3 */ gboolean -_ostree_repo_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error) +ostree_repo_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error) { g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); @@ -538,8 +539,8 @@ _ostree_repo_lock_push (OstreeRepo *self, } } -/* - * _ostree_repo_lock_pop: +/** + * ostree_repo_lock_pop: * @self: a #OstreeRepo * @cancellable: a #GCancellable * @error: a #GError @@ -560,11 +561,12 @@ _ostree_repo_lock_push (OstreeRepo *self, * %TRUE is returned. * * Returns: %TRUE on success, otherwise %FALSE with @error set + * Since: 2021.3 */ gboolean -_ostree_repo_lock_pop (OstreeRepo *self, - GCancellable *cancellable, - GError **error) +ostree_repo_lock_pop (OstreeRepo *self, + GCancellable *cancellable, + GError **error) { g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (OSTREE_IS_REPO (self), FALSE); @@ -628,7 +630,7 @@ _ostree_repo_lock_pop (OstreeRepo *self, } /* - * _ostree_repo_auto_lock_push: (skip) + * ostree_repo_auto_lock_push: (skip) * @self: a #OstreeRepo * @lock_type: the type of lock to acquire * @cancellable: a #GCancellable @@ -642,34 +644,37 @@ _ostree_repo_lock_pop (OstreeRepo *self, * * |[ * g_autoptr(OstreeRepoAutoLock) lock = NULL; - * lock = _ostree_repo_auto_lock_push (repo, lock_type, cancellable, error); + * lock = ostree_repo_auto_lock_push (repo, lock_type, cancellable, error); * if (!lock) * return FALSE; * ]| * * Returns: @self on success, otherwise %NULL with @error set + * Since: 2021.3 */ OstreeRepoAutoLock * -_ostree_repo_auto_lock_push (OstreeRepo *self, - OstreeRepoLockType lock_type, - GCancellable *cancellable, - GError **error) +ostree_repo_auto_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error) { - if (!_ostree_repo_lock_push (self, lock_type, cancellable, error)) + if (!ostree_repo_lock_push (self, lock_type, cancellable, error)) return NULL; return (OstreeRepoAutoLock *)self; } -/* - * _ostree_repo_auto_lock_cleanup: (skip) +/** + * ostree_repo_auto_lock_cleanup: (skip) * @lock: a #OstreeRepoAutoLock * * A cleanup handler for use with ostree_repo_auto_lock_push(). If @lock is * not %NULL, ostree_repo_lock_pop() will be called on it. If * ostree_repo_lock_pop() fails, a critical warning will be emitted. + * + * Since: 2021.3 */ void -_ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock) +ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock) { OstreeRepo *repo = lock; if (repo) @@ -677,7 +682,7 @@ _ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock) g_autoptr(GError) error = NULL; int errsv = errno; - if (!_ostree_repo_lock_pop (repo, NULL, &error)) + if (!ostree_repo_lock_pop (repo, NULL, &error)) g_critical ("Cleanup repo lock failed: %s", error->message); errno = errsv; @@ -5791,8 +5796,8 @@ ostree_repo_regenerate_summary (OstreeRepo *self, g_autoptr(OstreeRepoAutoLock) lock = NULL; gboolean no_deltas_in_summary = FALSE; - lock = _ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, - cancellable, error); + lock = ostree_repo_auto_lock_push (self, OSTREE_REPO_LOCK_EXCLUSIVE, + cancellable, error); if (!lock) return FALSE; diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index f94d70be..62e238c9 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -1498,6 +1498,56 @@ gboolean ostree_repo_regenerate_summary (OstreeRepo *self, GCancellable *cancellable, GError **error); + +/** + * OstreeRepoLockType: + * @OSTREE_REPO_LOCK_SHARED: A "read only" lock; multiple readers are allowed. + * @OSTREE_REPO_LOCK_EXCLUSIVE: A writable lock at most one writer can be active, and zero readers. + * + * Flags controlling repository locking. + * + * Since: 2021.3 + */ +typedef enum { + OSTREE_REPO_LOCK_SHARED, + OSTREE_REPO_LOCK_EXCLUSIVE +} OstreeRepoLockType; + +_OSTREE_PUBLIC +gboolean ostree_repo_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error); +_OSTREE_PUBLIC +gboolean ostree_repo_lock_pop (OstreeRepo *self, + GCancellable *cancellable, + GError **error); + +/* C convenience API only */ +#ifndef __GI_SCANNER__ + +/** + * OstreeRepoAutoLock: (skip) + * + * An opaque type for use with ostree_repo_auto_lock_push(). + * + * Since: 2021.3 + */ +typedef OstreeRepo OstreeRepoAutoLock; + +_OSTREE_PUBLIC +OstreeRepoAutoLock * ostree_repo_auto_lock_push (OstreeRepo *self, + OstreeRepoLockType lock_type, + GCancellable *cancellable, + GError **error); + +_OSTREE_PUBLIC +void ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoLock, ostree_repo_auto_lock_cleanup) + +#endif + + /** * OSTREE_REPO_METADATA_REF: * diff --git a/src/libostree/ostree-sysroot-cleanup.c b/src/libostree/ostree-sysroot-cleanup.c index 27122834..91381cb0 100644 --- a/src/libostree/ostree-sysroot-cleanup.c +++ b/src/libostree/ostree-sysroot-cleanup.c @@ -505,7 +505,7 @@ ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot, * the prune. */ g_autoptr(OstreeRepoAutoLock) lock = - _ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); + ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, cancellable, error); if (!lock) return FALSE; diff --git a/tests/test-core.js b/tests/test-core.js index 2c7162be..7d871c1f 100755 --- a/tests/test-core.js +++ b/tests/test-core.js @@ -134,4 +134,12 @@ w.write(inline_content.slice(10), null) let actual_checksum = w.finish(null) assertEquals(actual_checksum, networks_checksum) +// Basic locking API sanity test +repo.lock_push(OSTree.RepoLockType.SHARED, null); +repo.lock_push(OSTree.RepoLockType.SHARED, null); +repo.lock_pop(null); +repo.lock_pop(null); +repo.lock_push(OSTree.RepoLockType.EXCLUSIVE, null); +repo.lock_pop(null); + print("ok test-core"); diff --git a/tests/test-repo.c b/tests/test-repo.c index 9337ac3b..b388f5bf 100644 --- a/tests/test-repo.c +++ b/tests/test-repo.c @@ -249,6 +249,30 @@ test_write_regfile_api (Fixture *fixture, g_assert_cmpstr (checksum, ==, "23a2e97d21d960ac7a4e39a8721b1baff7b213e00e5e5641334f50506012fcff"); } +/* Just a sanity check of the C autolocking API */ +static void +test_repo_autolock (Fixture *fixture, + gconstpointer test_data) +{ + g_autoptr(GError) error = NULL; + g_autoptr(OstreeRepo) repo = ostree_repo_create_at (fixture->tmpdir.fd, ".", + OSTREE_REPO_MODE_ARCHIVE, + NULL, + NULL, &error); + g_assert_no_error (error); + + { + g_autoptr(OstreeRepoAutoLock) lock = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_EXCLUSIVE, NULL, &error); + g_assert_no_error (error); + } + + g_autoptr(OstreeRepoAutoLock) lock1 = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); + g_assert_no_error (error); + + g_autoptr(OstreeRepoAutoLock) lock2 = ostree_repo_auto_lock_push (repo, OSTREE_REPO_LOCK_SHARED, NULL, &error); + g_assert_no_error (error); +} + int main (int argc, char **argv) @@ -266,6 +290,8 @@ main (int argc, test_repo_get_min_free_space, teardown); g_test_add ("/repo/write_regfile_api", Fixture, NULL, setup, test_write_regfile_api, teardown); + g_test_add ("/repo/autolock", Fixture, NULL, setup, + test_repo_autolock, teardown); return g_test_run (); }