tdb_compat: support tdb_reopen/tdb_reopen_all for TDB2
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 13 Sep 2011 22:43:28 +0000 (08:13 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 13 Sep 2011 22:43:28 +0000 (08:13 +0930)
This matters with the clear-if-first support: we need to re-establish
those locks at this point.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
lib/tdb_compat/tdb_compat.c
lib/tdb_compat/tdb_compat.h

index 2e43564802242b62c872b9b643234eed3c93f2f6..6e4813b56e3f7874c505a3621295ea6477409e0f 100644 (file)
@@ -120,4 +120,50 @@ tdb_open_compat_(const char *name, int hash_size_unused,
        return tdb_open(name, tdb_flags|TDB_ALLOW_NESTING, open_flags, mode,
                        attr);
 }
+
+/* We only need these for the CLEAR_IF_FIRST lock. */
+static int reacquire_cif_lock(struct tdb_context *tdb, bool *fail)
+{
+       struct flock fl;
+       union tdb_attribute cif;
+
+       cif.openhook.base.attr = TDB_ATTRIBUTE_OPENHOOK;
+       cif.openhook.base.next = NULL;
+
+       if (tdb_get_attribute(tdb, &cif) != TDB_SUCCESS
+           || cif.openhook.fn != clear_if_first) {
+               return 0;
+       }
+
+       /* We hold a lock offset 4 always, so we can tell if anyone else is. */
+       fl.l_type = F_RDLCK;
+       fl.l_whence = SEEK_SET;
+       fl.l_start = 4; /* ACTIVE_LOCK */
+       fl.l_len = 1;
+       if (fcntl(tdb_fd(tdb), F_SETLKW, &fl) != 0) {
+               *fail = true;
+               return -1;
+       }
+       return 0;
+}
+
+int tdb_reopen(struct tdb_context *tdb)
+{
+       bool unused;
+       return reacquire_cif_lock(tdb, &unused);
+}
+
+int tdb_reopen_all(int parent_longlived)
+{
+       bool fail = false;
+
+       if (parent_longlived) {
+               return 0;
+       }
+
+       tdb_foreach(reacquire_cif_lock, &fail);
+       if (fail)
+               return -1;
+       return 0;
+}
 #endif
index 16d1f48c7d613108db092ccc167290c47e7e7926..1f7e8a9c63672491d8f6ca868cbe7f22ace5fada 100644 (file)
@@ -76,9 +76,9 @@ int64_t tdb_traverse_read_(struct tdb_context *tdb,
 /* This typedef doesn't exist in TDB2. */
 typedef struct tdb_context TDB_CONTEXT;
 
-/* We don't need these any more. */
-#define tdb_reopen_all(flag) 0
-#define tdb_reopen(tdb) 0
+/* We only need these for the CLEAR_IF_FIRST lock. */
+int tdb_reopen(struct tdb_context *tdb);
+int tdb_reopen_all(int parent_longlived);
 
 /* These no longer exist in tdb2. */
 #define TDB_CLEAR_IF_FIRST 1048576