tdb: more testcase fixup.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 23 Feb 2010 22:47:41 +0000 (09:17 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 23 Feb 2010 22:47:41 +0000 (09:17 +1030)
ccan/tdb/test/lock-tracking.c
ccan/tdb/test/lock-tracking.h
ccan/tdb/test/run-die-during-transaction.c

index bc4be14759211f6718bfda34d124652329d3544a..8c0c86c948b0151d4438cd6bb9f162721cf6d480 100644 (file)
@@ -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);
index 9afdd0978e475200642f8e665d8450213c31fc28..702fdf83e90592a295e1d3655952258fa22959a6 100644 (file)
@@ -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 */
index d80527f51b0e2147100a7bc12df22ea6bfca12b5..f8000b553e2ed029ed93785ceec7c24312c02d17 100644 (file)
@@ -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();