X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb%2Ftest%2Frun-open-during-transaction.c;h=908dc7da6c44309560793b4abecccff1113af316;hb=c4a9fd1b01822e75da853d3f3229de5d35409e31;hp=b0eed67b1f56a78519175a951a7360184697bb00;hpb=02b364ae6c3a120101aa1fd6eb0919994ca8ffb1;p=ccan diff --git a/ccan/tdb/test/run-open-during-transaction.c b/ccan/tdb/test/run-open-during-transaction.c index b0eed67b..908dc7da 100644 --- a/ccan/tdb/test/run-open-during-transaction.c +++ b/ccan/tdb/test/run-open-during-transaction.c @@ -1,13 +1,14 @@ #define _XOPEN_SOURCE 500 #include +#include "lock-tracking.h" + static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); static ssize_t write_check(int fd, const void *buf, size_t count); -static int fcntl_check(int fd, int cmd, ... /* arg */ ); static int ftruncate_check(int fd, off_t length); #define pwrite pwrite_check #define write write_check -#define fcntl fcntl_check +#define fcntl fcntl_with_lockcheck #define ftruncate ftruncate_check #include @@ -19,6 +20,7 @@ static int ftruncate_check(int fd, off_t length); #include #include #include +#include #include #include #include @@ -41,6 +43,20 @@ static bool clear_if_first; #undef fcntl #undef ftruncate +static void taplog(struct tdb_context *tdb, + enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char line[200]; + + va_start(ap, fmt); + vsprintf(line, fmt, ap); + va_end(ap); + + diag("%s", line); +} + static void save_file_contents(int fd) { struct stat st; @@ -66,7 +82,7 @@ static void check_for_agent(int fd, bool block) if (!external_agent_operation_check(agent, block, &res)) return; - if (res != 0) + if (res != 1) err(1, "Agent failed open"); agent_pending = false; @@ -92,6 +108,9 @@ static void check_for_agent(int fd, bool block) static void check_file_contents(int fd) { + if (!in_transaction) + return; + if (agent_pending) check_for_agent(fd, false); @@ -117,16 +136,14 @@ static ssize_t pwrite_check(int fd, { ssize_t ret; - if (in_transaction) - check_file_contents(fd); + check_file_contents(fd); snapshot_uptodate = false; ret = pwrite(fd, buf, count, offset); if (ret != count) return ret; - if (in_transaction) - check_file_contents(fd); + check_file_contents(fd); return ret; } @@ -134,8 +151,7 @@ static ssize_t write_check(int fd, const void *buf, size_t count) { ssize_t ret; - if (in_transaction) - check_file_contents(fd); + check_file_contents(fd); snapshot_uptodate = false; @@ -143,37 +159,7 @@ static ssize_t write_check(int fd, const void *buf, size_t count) if (ret != count) return ret; - if (in_transaction) - check_file_contents(fd); - return ret; -} - -/* This seems to be a macro for glibc... */ -extern int fcntl(int fd, int cmd, ... /* arg */ ); - -static int fcntl_check(int fd, int cmd, ... /* arg */ ) -{ - va_list ap; - int ret, arg3; - struct flock *fl; - - if (cmd != F_SETLK && cmd != F_SETLKW) { - /* This may be totally bogus, but we don't know in general. */ - va_start(ap, cmd); - arg3 = va_arg(ap, int); - va_end(ap); - - return fcntl(fd, cmd, arg3); - } - - va_start(ap, cmd); - fl = va_arg(ap, struct flock *); - va_end(ap); - - ret = fcntl(fd, cmd, fl); - - if (in_transaction && fl->l_type == F_UNLCK) - check_file_contents(fd); + check_file_contents(fd); return ret; } @@ -181,20 +167,19 @@ static int ftruncate_check(int fd, off_t length) { int ret; - if (in_transaction) - check_file_contents(fd); + check_file_contents(fd); snapshot_uptodate = false; ret = ftruncate(fd, length); - if (in_transaction) - check_file_contents(fd); + check_file_contents(fd); return ret; } int main(int argc, char *argv[]) { + struct tdb_logging_context logctx = { taplog, NULL }; const int flags[] = { TDB_DEFAULT, TDB_CLEAR_IF_FIRST, TDB_NOMMAP, @@ -204,6 +189,7 @@ int main(int argc, char *argv[]) TDB_DATA key, data; plan_tests(20); + unlock_callback = check_file_contents; agent = prepare_external_agent(); if (!agent) err(1, "preparing agent"); @@ -213,11 +199,15 @@ int main(int argc, char *argv[]) nice(15); for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { + clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); + diag("Test with %s and %s\n", + clear_if_first ? "CLEAR" : "DEFAULT", + (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); unlink(TEST_DBNAME); - tdb = tdb_open(TEST_DBNAME, 1024, flags[i], - O_CREAT|O_TRUNC|O_RDWR, 0600); + tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i], + O_CREAT|O_TRUNC|O_RDWR, 0600, + &logctx, NULL); ok1(tdb); - clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); ok1(tdb_transaction_start(tdb) == 0); in_transaction = true; @@ -230,7 +220,7 @@ int main(int argc, char *argv[]) ok1(tdb_transaction_commit(tdb) == 0); if (agent_pending) check_for_agent(tdb->fd, true); - ok(errors == 0, "We had %u errors", errors); + ok(errors == 0, "We had %u unexpected changes", errors); tdb_close(tdb); }