summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/tdb/common/transaction.c17
-rw-r--r--lib/tdb/test/run-transaction-expand.c14
-rw-r--r--lib/tdb/wscript4
3 files changed, 20 insertions, 15 deletions
diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c
index c3477eb80c..f18b4c229e 100644
--- a/lib/tdb/common/transaction.c
+++ b/lib/tdb/common/transaction.c
@@ -82,8 +82,9 @@
intervention.
- if TDB_NOSYNC is passed to flags in tdb_open then transactions are
- still available, but no transaction recovery area is used and no
- fsync/msync calls are made.
+ still available, but no fsync/msync calls are made. This means we
+ are still proof against a process dying during transaction commit,
+ but not against machine reboot.
- if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using
tdb_add_flags() transaction nesting is enabled.
@@ -976,13 +977,11 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb)
return -1;
}
- if (!(tdb->flags & TDB_NOSYNC)) {
- /* write the recovery data to the end of the file */
- if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n"));
- _tdb_transaction_cancel(tdb);
- return -1;
- }
+ /* write the recovery data to the end of the file */
+ if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) {
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n"));
+ _tdb_transaction_cancel(tdb);
+ return -1;
}
tdb->transaction->prepared = true;
diff --git a/lib/tdb/test/run-transaction-expand.c b/lib/tdb/test/run-transaction-expand.c
index 3b79dbb6ea..bc22d2b53e 100644
--- a/lib/tdb/test/run-transaction-expand.c
+++ b/lib/tdb/test/run-transaction-expand.c
@@ -1,8 +1,10 @@
#include "../common/tdb_private.h"
-/* Speed up the tests: setting TDB_NOSYNC removed recovery altogether. */
+/* Speed up the tests, but do the actual sync tests. */
+static unsigned int sync_counts = 0;
static inline int fake_fsync(int fd)
{
+ sync_counts++;
return 0;
}
#define fsync fake_fsync
@@ -10,6 +12,7 @@ static inline int fake_fsync(int fd)
#ifdef MS_SYNC
static inline int fake_msync(void *addr, size_t length, int flags)
{
+ sync_counts++;
return 0;
}
#define msync fake_msync
@@ -18,6 +21,7 @@ static inline int fake_msync(void *addr, size_t length, int flags)
#ifdef HAVE_FDATASYNC
static inline int fake_fdatasync(int fd)
{
+ sync_counts++;
return 0;
}
#define fdatasync fake_fdatasync
@@ -59,7 +63,10 @@ int main(int argc, char *argv[])
struct tdb_record rec;
tdb_off_t off;
- plan_tests(4);
+ /* Do *not* suppress sync for this test; we do it ourselves. */
+ unsetenv("TDB_NO_FSYNC");
+
+ plan_tests(5);
tdb = tdb_open_ex("run-transaction-expand.tdb",
1024, TDB_CLEAR_IF_FIRST,
O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
@@ -103,6 +110,9 @@ int main(int argc, char *argv[])
/* We should only be about 4 times larger than largest record. */
ok1(tdb->map_size < 5 * i * getpagesize());
+
+ /* We should have synchronized multiple times. */
+ ok1(sync_counts);
tdb_close(tdb);
free(data.dptr);
diff --git a/lib/tdb/wscript b/lib/tdb/wscript
index 01b4892fb0..e28e43acac 100644
--- a/lib/tdb/wscript
+++ b/lib/tdb/wscript
@@ -185,10 +185,6 @@ def testonly(ctx):
if not os.path.exists(link):
os.symlink(os.path.abspath(os.path.join(env.cwd, 'test')), link)
- # unset TDB_NO_FSYNC, since we want to test sync code.
- if 'TDB_NO_FSYNC' in os.environ:
- del os.environ['TDB_NO_FSYNC']
-
for f in 'tdb1-run-3G-file', 'tdb1-run-bad-tdb-header', 'tdb1-run', 'tdb1-run-check', 'tdb1-run-corrupt', 'tdb1-run-die-during-transaction', 'tdb1-run-endian', 'tdb1-run-incompatible', 'tdb1-run-nested-transactions', 'tdb1-run-nested-traverse', 'tdb1-run-no-lock-during-traverse', 'tdb1-run-oldhash', 'tdb1-run-open-during-transaction', 'tdb1-run-readonly-check', 'tdb1-run-rwlock-check', 'tdb1-run-summary', 'tdb1-run-transaction-expand', 'tdb1-run-traverse-in-transaction', 'tdb1-run-wronghash-fail', 'tdb1-run-zero-append':
cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(Utils.g_module.blddir, f)) + " > test-output 2>&1"
print("..." + f)