repo: Make locking APIs public
authorColin Walters <walters@verbum.org>
Thu, 15 Apr 2021 00:43:53 +0000 (20:43 -0400)
committerDan Nicholson <dbn@endlessos.org>
Sat, 5 Jun 2021 15:00:21 +0000 (09:00 -0600)
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
12 files changed:
Makefile-libostree.am
apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-repo-commit.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo-prune.c
src/libostree/ostree-repo-static-delta-core.c
src/libostree/ostree-repo.c
src/libostree/ostree-repo.h
src/libostree/ostree-sysroot-cleanup.c
tests/test-core.js
tests/test-repo.c

index dd396974064ae6c8107864bad34552bcc5b6e7e6..d40de48d13fe8c7cd9c5d4458ae0e60aa3a55e29 100644 (file)
@@ -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=
index b09ba6f9971ef3c3a2e32a3f61c3bfbe72e20ca0..2da1d749695c831d2475bae27b68a6bb3f273731 100644 (file)
@@ -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
index e3cd14a4afe56c8312e676914df80f6d08d329e0..1af5f449244ad20a399c2f4be612b3f210f9a744 100644 (file)
    - 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
index 1ac53259f22df430342153d6deef62bf0d4933fd..dd5cd8626b4aca7aeb863f5de78f07b4f6e4cd42 100644 (file)
@@ -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;
     }
index 14b29c0bbaa4123b16bbb6bec8388e9679d40383..20af1b38c48ab5399e979ff8161f5155c8c6d3a7 100644 (file)
@@ -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);
 
index 0b9536281969e042161f1a0129205dbf704a28f2..c4ce64abca3fefc1a50df0023f32fb10ea22e390 100644 (file)
@@ -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;
 
index e4280af01eb4a5de6db848337f2b771a6002ec71..d8c33b7c29d83d5d9d34eae6efc465d2b67c8018 100644 (file)
@@ -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;
 
index 76b02482b332e5faab79c52d941988f84bc2be55..1036a81f71d1bf23685bcc4c75959efb3f0657c4 100644 (file)
@@ -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;
 
index f94d70be1d1224d7e821393c514678efa23f48c0..62e238c9fdafd68f0db6b573be214e984f94b853 100644 (file)
@@ -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:
  *
index 27122834054b8b493d8aa85b3bc63d44aa02feec..91381cb0c6ae6f7a8f590b46ba66e3e017722952 100644 (file)
@@ -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;
 
index 2c7162be52561d0889780f3d0b8a4af2e9404e2a..7d871c1ffe5214a958938de7225ece630ae61e4c 100755 (executable)
@@ -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");
index 9337ac3bd330311366b2b36edeabf9bab145b382..b388f5bf87b69db9306e4883a9aa0d605a29c841 100644 (file)
@@ -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 ();
 }