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.
ostreedev/ostree#2337

Closes: ostreedev/ostree#2286

(cherry picked from commit 0f36d8c)

The new symbols have been added to the released symbols file rather than
the development symbols file as in the upstream PR since our package
does a released build. Similarly, the upstream `LIBOSTREE_2021.3` symbol
version has been used so that packages don't need to be rebuilt when we
get to that version and drop our backported commits.

https://phabricator.endlessm.com/T31868
  • Loading branch information
cgwalters authored and dbnicholson committed Jun 7, 2021
1 parent ce5633f commit a8b52f6
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 59 deletions.
6 changes: 6 additions & 0 deletions apidoc/ostree-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,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
12 changes: 12 additions & 0 deletions src/libostree/libostree-released.sym
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,18 @@ global:
ostree_repo_gpg_sign_data;
} LIBOSTREE_2020.7;

/* Endless backported symbols. Note that the upstream symbol version is
* used so that programs linking to the symbols don't need to be rebuilt
* when we get to the upstream release containing the symbols.
*/
LIBOSTREE_2021.3 {
global:
ostree_repo_auto_lock_push;
ostree_repo_auto_lock_cleanup;
ostree_repo_lock_push;
ostree_repo_lock_pop;
} LIBOSTREE_2020.8;

/* NOTE: Only add more content here in release commits! See the
* comments at the top of this file.
*/
8 changes: 4 additions & 4 deletions src/libostree/ostree-repo-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1794,8 +1794,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 @@ -2451,7 +2451,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 @@ -2509,7 +2509,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 @@ -496,30 +496,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_tmpf_fsverity_core (GLnxTmpfile *tmpf,
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 @@ -1268,7 +1268,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 @@ -5831,8 +5836,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 @@ -1466,6 +1466,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 @@ -70,4 +70,12 @@ repo.commit_transaction(null, null);
[,readCommit] = repo.resolve_rev('someref', true);
assertEquals(readCommit, null);

// 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");
27 changes: 26 additions & 1 deletion tests/test-repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,30 @@ test_repo_get_min_free_space (Fixture *fixture,
}
}

/* 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 @@ -212,7 +236,8 @@ main (int argc,
test_repo_equal, teardown);
g_test_add ("/repo/get_min_free_space", Fixture, NULL, setup,
test_repo_get_min_free_space, teardown);

g_test_add ("/repo/autolock", Fixture, NULL, setup,
test_repo_autolock, teardown);

return g_test_run ();
}
2 changes: 1 addition & 1 deletion tests/test-symbols.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ echo 'ok documented symbols'

# ONLY update this checksum in release commits!
cat > released-sha256.txt <<EOF
3e677623543b7fdc57b0e3d9c66eb477105b014411259762a328c1b5e82068f0 ${released_syms}
ed83cec94e3a642b35db8ecef1b3d6030ceefc81750d62e3d2f3f41625702bc4 ${released_syms}
EOF
sha256sum -c released-sha256.txt

Expand Down

0 comments on commit a8b52f6

Please sign in to comment.