Skip to content

Commit

Permalink
repo: Make locking APIs public
Browse files Browse the repository at this point in the history
Doing anything even somewhat sophisticated requires this;
turns out our own `ostree prune` CLI wants this, e.g.
#2337

Closes: #2286
  • Loading branch information
cgwalters authored and dbnicholson committed Jun 5, 2021
1 parent a7b590f commit 0f36d8c
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 60 deletions.
6 changes: 3 additions & 3 deletions Makefile-libostree.am
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
6 changes: 6 additions & 0 deletions apidoc/ostree-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/libostree/libostree-devel.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/libostree/ostree-repo-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
24 changes: 0 additions & 24 deletions src/libostree/ostree-repo-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
8 changes: 4 additions & 4 deletions src/libostree/ostree-repo-prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/libostree/ostree-repo-static-delta-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
51 changes: 28 additions & 23 deletions src/libostree/ostree-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -642,42 +644,45 @@ _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)
{
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;
Expand Down Expand Up @@ -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;

Expand Down
50 changes: 50 additions & 0 deletions src/libostree/ostree-repo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*
Expand Down
2 changes: 1 addition & 1 deletion src/libostree/ostree-sysroot-cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 8 additions & 0 deletions tests/test-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
26 changes: 26 additions & 0 deletions tests/test-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 ();
}

0 comments on commit 0f36d8c

Please sign in to comment.