]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4/torture: add a test for ctdb-tombstrone-record deadlock
authorRalph Boehme <slow@samba.org>
Sat, 23 Jul 2016 09:08:13 +0000 (11:08 +0200)
committerKarolin Seeger <kseeger@samba.org>
Wed, 10 Aug 2016 09:37:23 +0000 (11:37 +0200)
This tests for a possible deadlock between smbd and ctdb dealing with
ctdb tombstone records.

Commit 925625b52886d40b50fc631bad8bdc81970f7598 explains the deadlock in
more details and contains the fix. It's a fix for a regression
introduced by the patch for bug 10008 (1cae59ce112c).

If you ever want to use this test against that specific commit:

$ git checkout 925625b52886d40b50fc631bad8bdc81970f7598
$ git cherry-pick THIS_COMMIT

This should not deadlock on a ctdb cluster.

$ git revert 925625b52886d40b50fc631bad8bdc81970f7598

This will deadlock.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=12005

Pair-Programmed-With: Michael Adam <obnox@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
(cherry picked from commit b17e2f5c740fb081c007ed2e1c23138ffcba1469)

source4/torture/smb2/lock.c

index 68e353dee4620a5c3c907c8d41c44a5fc6a77b15..3900abf50ad0657ce18a7771e6a0c2cfd9b6d510 100644 (file)
@@ -3033,6 +3033,69 @@ done:
        return ret;
 }
 
+/**
+ * Test lock interaction between smbd and ctdb with tombstone records.
+ *
+ * Re-locking an unlocked record could lead to a deadlock between
+ * smbd and ctdb. Make sure we don't regress.
+ *
+ * https://bugzilla.samba.org/show_bug.cgi?id=12005
+ * https://bugzilla.samba.org/show_bug.cgi?id=10008
+ */
+static bool test_deadlock(struct torture_context *torture,
+                         struct smb2_tree *tree)
+{
+       NTSTATUS status;
+       bool ret = true;
+       struct smb2_handle _h;
+       struct smb2_handle *h = NULL;
+       uint8_t buf[200];
+       const char *fname = BASEDIR "\\deadlock.txt";
+
+       if (!lpcfg_clustering(torture->lp_ctx)) {
+               torture_skip(torture, "Test must be run on a ctdb cluster\n");
+               return true;
+       }
+
+       status = torture_smb2_testdir(tree, BASEDIR, &_h);
+       torture_assert_ntstatus_ok(torture, status,
+                                  "torture_smb2_testdir failed");
+       smb2_util_close(tree, _h);
+
+       status = torture_smb2_testfile(tree, fname, &_h);
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "torture_smb2_testfile failed");
+       h = &_h;
+
+       ZERO_STRUCT(buf);
+       status = smb2_util_write(tree, *h, buf, 0, ARRAY_SIZE(buf));
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "smb2_util_write failed");
+
+       status = test_smb2_lock(tree, *h, 0, 1, true);
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "test_smb2_lock failed");
+
+       status = test_smb2_unlock(tree, *h, 0, 1);
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "test_smb2_unlock failed");
+
+       status = test_smb2_lock(tree, *h, 0, 1, true);
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "test_smb2_lock failed");
+
+       status = test_smb2_unlock(tree, *h, 0, 1);
+       torture_assert_ntstatus_ok_goto(torture, status, ret, done,
+                                       "test_smb2_unlock failed");
+
+done:
+       if (h != NULL) {
+               smb2_util_close(tree, *h);
+       }
+       smb2_deltree(tree, BASEDIR);
+       return ret;
+}
+
 /* basic testing of SMB2 locking
 */
 struct torture_suite *torture_smb2_lock_init(void)
@@ -3068,6 +3131,7 @@ struct torture_suite *torture_smb2_lock_init(void)
        torture_suite_add_2smb2_test(suite, "overlap", test_overlap);
        torture_suite_add_1smb2_test(suite, "truncate", test_truncate);
        torture_suite_add_1smb2_test(suite, "replay", test_replay);
+       torture_suite_add_1smb2_test(suite, "ctdb-delrec-deadlock", test_deadlock);
 
        suite->description = talloc_strdup(suite, "SMB2-LOCK tests");