summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-07-01 12:05:07 -0700
committerKarolin Seeger <kseeger@samba.org>2014-07-15 12:46:16 +0200
commit7eb800dc5068b46c30efd5993bb1c30df5e5048e (patch)
tree254ccd9c9d05b8b66035feeb5a3bd694400cf518
parent2f118b639cf1eb1579b8554d42b18b31a5b222dd (diff)
downloadsamba-7eb800dc5068b46c30efd5993bb1c30df5e5048e.tar.gz
s4: smbtorture: Add multi-lock test. Regression test for bug #10684.
Bug #10684 - SMB1 blocking locks can fail notification on unlock, causing client timeout. https://bugzilla.samba.org/show_bug.cgi?id=10684 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE> (cherry picked from commit 64346a134dac2bd023f7473202ca38d35ffd3c89)
-rw-r--r--source4/torture/raw/lock.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c
index a31a4d0cfb1..8dc2434b72c 100644
--- a/source4/torture/raw/lock.c
+++ b/source4/torture/raw/lock.c
@@ -2262,6 +2262,102 @@ done:
smbcli_deltree(cli->tree, BASEDIR);
return ret;
}
+/*
+ test multi Locking&X operation
+*/
+static bool test_multilock(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ union smb_lock io;
+ struct smb_lock_entry lock[2];
+ NTSTATUS status;
+ bool ret = true;
+ int fnum;
+ const char *fname = BASEDIR "\\multilock_test.txt";
+ time_t t;
+ struct smbcli_request *req;
+ struct smbcli_session_options options;
+
+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
+
+ lpcfg_smbcli_session_options(tctx->lp_ctx, &options);
+
+ torture_comment(tctx, "Testing LOCKING_ANDX multi-lock\n");
+ io.generic.level = RAW_LOCK_LOCKX;
+
+ /* Create the test file. */
+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx,
+ "Failed to create %s - %s\n",
+ fname, smbcli_errstr(cli->tree)));
+
+ /*
+ * Lock regions 100->109, 110->119 as
+ * two separate write locks in one request.
+ */
+ io.lockx.level = RAW_LOCK_LOCKX;
+ io.lockx.in.file.fnum = fnum;
+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 2;
+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK;
+ lock[0].pid = cli->session->pid;
+ lock[0].offset = 100;
+ lock[0].count = 10;
+ lock[1].pid = cli->session->pid;
+ lock[1].offset = 120;
+ lock[1].count = 10;
+ io.lockx.in.locks = &lock[0];
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /*
+ * Now request the same locks on a different
+ * context as blocking locks with infinite timeout.
+ */
+
+ io.lockx.in.timeout = -1;
+ lock[0].pid = cli->session->pid+1;
+ lock[1].pid = cli->session->pid+1;
+ req = smb_raw_lock_send(cli->tree, &io);
+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx,
+ "Failed to setup timed locks (%s)\n", __location__));
+
+ /* Unlock lock[0] */
+ io.lockx.in.timeout = 0;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ io.lockx.in.locks = &lock[0];
+ lock[0].pid = cli->session->pid;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* Start the clock. */
+ t = time_mono(NULL);
+
+ /* Unlock lock[1] */
+ io.lockx.in.timeout = 0;
+ io.lockx.in.ulock_cnt = 1;
+ io.lockx.in.lock_cnt = 0;
+ io.lockx.in.locks = &lock[1];
+ lock[1].pid = cli->session->pid;
+ status = smb_raw_lock(cli->tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* receive the successful blocked lock requests */
+ status = smbcli_request_simple_recv(req);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* Fail if this took more than 2 seconds. */
+ torture_assert(tctx,!(time_mono(NULL) > t+2), talloc_asprintf(tctx,
+ "Blocking locks were not granted immediately (%s)\n",
+ __location__));
+done:
+ smb_raw_exit(cli->session);
+ smbcli_deltree(cli->tree, BASEDIR);
+ return ret;
+}
/*
basic testing of lock calls
@@ -2283,6 +2379,7 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx)
test_multiple_unlock);
torture_suite_add_1smb_test(suite, "zerobytelocks", test_zerobytelocks);
torture_suite_add_1smb_test(suite, "zerobyteread", test_zerobyteread);
+ torture_suite_add_1smb_test(suite, "multilock", test_multilock);
return suite;
}