Browse Source

tdb: more testcase fixup.

Rusty Russell 16 years ago
parent
commit
d0b36a7cb7

+ 20 - 7
ccan/tdb/test/lock-tracking.c

@@ -4,6 +4,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <ccan/tap/tap.h>
+#include <ccan/tdb/tdb_private.h>
 
 struct lock {
 	struct lock *next;
@@ -13,6 +14,7 @@ struct lock {
 };
 static struct lock *locks;
 int locking_errors = 0;
+bool suppress_lockcheck = false;
 void (*unlock_callback)(int fd);
 
 int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ )
@@ -47,7 +49,7 @@ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ )
 				break;
 			}
 		}
-		if (!old) {
+		if (!old && !suppress_lockcheck) {
 			diag("Unknown unlock %u@%u",
 			     (int)fl->l_len, (int)fl->l_start);
 			locking_errors++;
@@ -70,11 +72,22 @@ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ )
 				break;
 		}
 		if (i) {
-			diag("%s lock %u@%u overlaps %u@%u",
-			     fl->l_type == F_WRLCK ? "write" : "read",
-			     (int)fl->l_len, (int)fl->l_start,
-			     i->len, (int)i->off);
-			locking_errors++;
+			/* Special case: upgrade of allrecord lock. */
+			if (i->type == F_RDLCK && fl->l_type == F_WRLCK
+			    && i->off == FREELIST_TOP
+			    && fl->l_start == FREELIST_TOP
+			    && i->len == 0
+			    && fl->l_len == 0) {
+				i->type = F_WRLCK;
+				goto ok;
+			}
+			if (!suppress_lockcheck) {
+				diag("%s lock %u@%u overlaps %u@%u",
+				     fl->l_type == F_WRLCK ? "write" : "read",
+				     (int)fl->l_len, (int)fl->l_start,
+				     i->len, (int)i->off);
+				locking_errors++;
+			}
 		}
 		new = malloc(sizeof *new);
 		new->off = fl->l_start;
@@ -83,7 +96,7 @@ int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ )
 		new->next = locks;
 		locks = new;
 	}
-
+ok:
 	ret = fcntl(fd, cmd, fl);
 	if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback)
 		unlock_callback(fd);

+ 5 - 0
ccan/tdb/test/lock-tracking.h

@@ -1,5 +1,7 @@
 #ifndef LOCK_TRACKING_H
 #define LOCK_TRACKING_H
+#include <stdbool.h>
+
 /* Set this if you want a callback after fnctl unlock. */
 extern void (*unlock_callback)(int fd);
 
@@ -11,4 +13,7 @@ unsigned int forget_locking(void);
 
 /* Number of errors in locking. */
 extern int locking_errors;
+
+/* Suppress lock checking. */
+extern bool suppress_lockcheck;
 #endif /* LOCK_TRACKING_H */

+ 4 - 2
ccan/tdb/test/run-die-during-transaction.c

@@ -116,6 +116,7 @@ reset:
 	if (setjmp(jmpbuf) != 0) {
 		/* We're partway through.  Simulate our death. */
 		close(tdb->fd);
+		forget_locking();
 		in_transaction = false;
 
 		if (external_agent_operation(agent, NEEDS_RECOVERY_KEEP_OPENED,
@@ -144,11 +145,12 @@ reset:
 		external_agent_operation(agent, CLOSE, "");
 		/* Suppress logging as this tries to use closed fd. */
 		suppress_logging = true;
+		suppress_lockcheck = true;
 		tdb_close(tdb);
 		suppress_logging = false;
+		suppress_lockcheck = false;
 		target++;
 		current = 0;
-		forget_locking();
 		goto reset;
 	}
 
@@ -195,7 +197,7 @@ int main(int argc, char *argv[])
 	struct agent *agent;
 	int i;
 
-	plan_tests(6);
+	plan_tests(12);
 	unlock_callback = maybe_die;
 
 	agent = prepare_external_agent();