mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-09 01:18:35 +03:00
repo: Make locking APIs public
Doing anything even somewhat sophisticated requires this; turns out our own `ostree prune` CLI wants this, e.g. https://github.com/ostreedev/ostree/issues/2337 Closes: https://github.com/ostreedev/ostree/issues/2286
This commit is contained in:
parent
a7b590f7ae
commit
0f36d8c221
@ -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=
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* 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;
|
||||
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user