The Samba-Bugzilla – Attachment 11234 Details for
Bug 11381
winbind failing to respond
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Reproducer
look (text/plain), 6.39 KB, created by
Volker Lendecke
on 2015-07-06 09:46:23 UTC
(
hide
)
Description:
Reproducer
Filename:
MIME Type:
Creator:
Volker Lendecke
Created:
2015-07-06 09:46:23 UTC
Size:
6.39 KB
patch
obsolete
>From 10315ae5291eb3f11f4ee9a94e18e963b663b48a Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 6 Jul 2015 10:49:47 +0200 >Subject: [PATCH] tdb: Reproducer for Bug 11381 > >Signed-off-by: Volker Lendecke <vl@samba.org> >--- > lib/tdb/test/run-allrecord-traverse-deadlock.c | 203 ++++++++++++++++++++++++ > lib/tdb/wscript | 1 + > 2 files changed, 204 insertions(+) > create mode 100644 lib/tdb/test/run-allrecord-traverse-deadlock.c > >diff --git a/lib/tdb/test/run-allrecord-traverse-deadlock.c b/lib/tdb/test/run-allrecord-traverse-deadlock.c >new file mode 100644 >index 0000000..4c6c769 >--- /dev/null >+++ b/lib/tdb/test/run-allrecord-traverse-deadlock.c >@@ -0,0 +1,203 @@ >+#include "../common/tdb_private.h" >+#include "../common/io.c" >+#include "../common/tdb.c" >+#include "../common/lock.c" >+#include "../common/freelist.c" >+#include "../common/traverse.c" >+#include "../common/transaction.c" >+#include "../common/error.c" >+#include "../common/open.c" >+#include "../common/check.c" >+#include "../common/hash.c" >+#include "../common/mutex.c" >+#include "tap-interface.h" >+#include <stdlib.h> >+#include <sys/types.h> >+#include <sys/wait.h> >+#include <stdarg.h> >+#include "logging.h" >+ >+static void do_allrecord_lock(const char *name, int tdb_flags, int up, >+ int down) >+{ >+ struct tdb_context *tdb; >+ int ret; >+ ssize_t nread, nwritten; >+ char c = 0; >+ >+ tdb = tdb_open_ex(name, 3, tdb_flags, >+ O_RDWR|O_CREAT, 0755, &taplogctx, NULL); >+ ok(tdb, "tdb_open_ex should succeed"); >+ >+ ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); >+ ok(ret == 0, "tdb_allrecord_lock should succeed"); >+ >+ nwritten = write(up, &c, sizeof(c)); >+ ok(nwritten == sizeof(c), "write should succeed"); >+ >+ nread = read(down, &c, sizeof(c)); >+ ok(nread == sizeof(c), "read should succeed"); >+ >+ ret = tdb_traverse(tdb, NULL, NULL); >+ ok(ret == -1, "do_allrecord_lock: traverse should fail"); >+ >+ nwritten = write(up, &c, sizeof(c)); >+ ok(nwritten == sizeof(c), "write should succeed"); >+ >+ exit(0); >+} >+ >+static void do_traverse(const char *name, int tdb_flags, int up, int down) >+{ >+ struct tdb_context *tdb; >+ int ret; >+ ssize_t nread, nwritten; >+ char c = 0; >+ >+ tdb = tdb_open_ex(name, 3, tdb_flags, >+ O_RDWR|O_CREAT, 0755, &taplogctx, NULL); >+ ok(tdb, "tdb_open_ex should succeed"); >+ >+ ret = tdb_traverse(tdb, NULL, NULL); >+ ok(ret == 1, "do_traverse: tdb_traverse should return 1 record"); >+ >+ nwritten = write(up, &c, sizeof(c)); >+ ok(nwritten == sizeof(c), "write should succeed"); >+ >+ nread = read(down, &c, sizeof(c)); >+ ok(nread == sizeof(c), "read should succeed"); >+ >+ exit(0); >+} >+ >+/* >+ * Process 1: get the allrecord_lock on a tdb. >+ * Process 2: Start a traverse, this will stall waiting for first chainlock >+ * Process 1: Start a traverse: This will get EDEADLK in trying to >+ * get the TRANSACTION_LOCK. It will deadlock for mutexes >+ */ >+ >+static int do_tests(const char *name, int tdb_flags) >+{ >+ struct tdb_context *tdb; >+ int ret; >+ pid_t traverse_child, allrecord_child; >+ int traverse_down[2]; >+ int traverse_up[2]; >+ int allrecord_down[2]; >+ int allrecord_up[2]; >+ char c; >+ ssize_t nread, nwritten; >+ TDB_DATA key, data; >+ >+ key.dsize = strlen("hi"); >+ key.dptr = discard_const_p(uint8_t, "hi"); >+ data.dsize = strlen("world"); >+ data.dptr = discard_const_p(uint8_t, "world"); >+ >+ tdb = tdb_open_ex(name, 3, tdb_flags, >+ O_RDWR|O_CREAT, 0755, &taplogctx, NULL); >+ ok(tdb, "tdb_open_ex should succeed"); >+ >+ ret = tdb_store(tdb, key, data, TDB_INSERT); >+ ok(ret == 0, "tdb_store should succeed"); >+ >+ ret = pipe(traverse_down); >+ ok(ret == 0, "pipe should succeed"); >+ >+ ret = pipe(traverse_up); >+ ok(ret == 0, "pipe should succeed"); >+ >+ ret = pipe(allrecord_down); >+ ok(ret == 0, "pipe should succeed"); >+ >+ ret = pipe(allrecord_up); >+ ok(ret == 0, "pipe should succeed"); >+ >+ allrecord_child = fork(); >+ ok(allrecord_child != -1, "fork should succeed"); >+ >+ if (allrecord_child == 0) { >+ tdb_close(tdb); >+ close(traverse_up[0]); >+ close(traverse_up[1]); >+ close(traverse_down[0]); >+ close(traverse_down[1]); >+ close(allrecord_up[0]); >+ close(allrecord_down[1]); >+ do_allrecord_lock(name, tdb_flags, >+ allrecord_up[1], allrecord_down[0]); >+ exit(0); >+ } >+ close(allrecord_up[1]); >+ close(allrecord_down[0]); >+ >+ nread = read(allrecord_up[0], &c, sizeof(c)); >+ ok(nread == sizeof(c), "read should succeed"); >+ >+ traverse_child = fork(); >+ ok(traverse_child != -1, "fork should succeed"); >+ >+ if (traverse_child == 0) { >+ tdb_close(tdb); >+ close(traverse_up[0]); >+ close(traverse_down[1]); >+ close(allrecord_up[0]); >+ close(allrecord_up[1]); >+ close(allrecord_down[0]); >+ close(allrecord_down[1]); >+ do_traverse(name, tdb_flags, >+ traverse_up[1], traverse_down[0]); >+ exit(0); >+ } >+ close(traverse_up[1]); >+ close(traverse_down[0]); >+ >+ poll(NULL, 0, 1000); >+ >+ nwritten = write(allrecord_down[1], &c, sizeof(c)); >+ ok(nwritten == sizeof(c), "write should succeed"); >+ >+ nread = read(traverse_up[0], &c, sizeof(c)); >+ ok(nread == sizeof(c), "read should succeed"); >+ >+ nwritten = write(traverse_down[1], &c, sizeof(c)); >+ ok(nwritten == sizeof(c), "write should succeed"); >+ >+ nread = read(allrecord_up[0], &c, sizeof(c)); >+ ok(nread == sizeof(c), "ret should succeed"); >+ >+ close(traverse_up[0]); >+ close(traverse_down[1]); >+ close(allrecord_up[0]); >+ close(allrecord_down[1]); >+ diag("%s tests done", name); >+ return exit_status(); >+} >+ >+int main(int argc, char *argv[]) >+{ >+ int ret; >+ bool mutex_support; >+ >+ mutex_support = tdb_runtime_check_for_robust_mutexes(); >+ >+ ret = do_tests("marklock-deadlock-fcntl.tdb", >+ TDB_CLEAR_IF_FIRST | >+ TDB_INCOMPATIBLE_HASH); >+ ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); >+ >+ if (!mutex_support) { >+ skip(1, "No robust mutex support, " >+ "skipping marklock-deadlock-mutex.tdb tests"); >+ return exit_status(); >+ } >+ >+ ret = do_tests("marklock-deadlock-mutex.tdb", >+ TDB_CLEAR_IF_FIRST | >+ TDB_MUTEX_LOCKING | >+ TDB_INCOMPATIBLE_HASH); >+ ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); >+ >+ return exit_status(); >+} >diff --git a/lib/tdb/wscript b/lib/tdb/wscript >index b283795..6d9791c 100644 >--- a/lib/tdb/wscript >+++ b/lib/tdb/wscript >@@ -41,6 +41,7 @@ tdb1_unit_tests = [ > 'run-wronghash-fail', > 'run-zero-append', > 'run-marklock-deadlock', >+ 'run-allrecord-traverse-deadlock', > 'run-mutex-openflags2', > 'run-mutex-trylock', > 'run-mutex-allrecord-bench', >-- >1.7.9.5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11381
:
11229
|
11230
|
11231
| 11234 |
11235
|
11304