From 655bdb19bd91c43b2c5230927bfa8343a0c8a56a Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Wed, 16 Dec 2009 14:38:56 -0800 Subject: s4/torture: add more lock cancellation tests * Test the SMB1 behavior when multiple lock ranges are requested, pend, and then are cancelled. The entire LockingAndX request fails. --- source4/torture/raw/lock.c | 97 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c index 34b05b70e4..0af73e503a 100644 --- a/source4/torture/raw/lock.c +++ b/source4/torture/raw/lock.c @@ -647,6 +647,99 @@ static bool test_async(struct torture_context *tctx, status = smb_raw_lock(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); + /* If a lock request contained multiple ranges and we are cancelling + * one while it's still pending, what happens? */ + torture_comment(tctx, "testing cancel 1/2 lock request\n"); + + /* Send request with two ranges */ + io.lockx.in.timeout = -1; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 2; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = lock; + req = smb_raw_lock_send(cli->tree, &io); + torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, + "Failed to setup pending lock (%s)\n", __location__)); + + /* Try to cancel the first lock range */ + io.lockx.in.timeout = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[0]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Locking request should've failed and second range should be + * unlocked */ + status = smbcli_request_simple_recv(req); + CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); + + io.lockx.in.timeout = 0; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[1]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Cleanup both locks */ + io.lockx.in.ulock_cnt = 2; + io.lockx.in.lock_cnt = 0; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = lock; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + torture_comment(tctx, "testing cancel 2/2 lock request\n"); + + /* Lock second range so it contends */ + io.lockx.in.timeout = 0; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[1]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Send request with two ranges */ + io.lockx.in.timeout = -1; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 2; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = lock; + req = smb_raw_lock_send(cli->tree, &io); + torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, + "Failed to setup pending lock (%s)\n", __location__)); + + /* Try to cancel the second lock range */ + io.lockx.in.timeout = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[1]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Locking request should've failed and first range should be + * unlocked */ + status = smbcli_request_simple_recv(req); + CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); + + io.lockx.in.timeout = 0; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = &lock[0]; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Cleanup both locks */ + io.lockx.in.ulock_cnt = 2; + io.lockx.in.lock_cnt = 0; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; + io.lockx.in.locks = lock; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + torture_comment(tctx, "testing cancel by unlock\n"); io.lockx.in.ulock_cnt = 0; io.lockx.in.lock_cnt = 1; @@ -654,7 +747,7 @@ static bool test_async(struct torture_context *tctx, io.lockx.in.timeout = 0; io.lockx.in.locks = &lock[0]; status = smb_raw_lock(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + CHECK_STATUS(status, NT_STATUS_OK); io.lockx.in.timeout = 5000; req = smb_raw_lock_send(cli->tree, &io); @@ -680,7 +773,7 @@ static bool test_async(struct torture_context *tctx, io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; io.lockx.in.timeout = 0; status = smb_raw_lock(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); t = time(NULL); io.lockx.in.timeout = 10000; -- cgit