Skip to content

Commit

Permalink
s4/torture: additional tests for kernel-oplocks
Browse files Browse the repository at this point in the history
Signed-off-by: Ralph Boehme <[email protected]>
Reviewed-by: Richard Sharpe <[email protected]>
(backported from commit bbc225d)
  • Loading branch information
slowfranklin authored and kseeger committed Aug 14, 2017
1 parent c03af9f commit 12c818b
Showing 1 changed file with 185 additions and 0 deletions.
185 changes: 185 additions & 0 deletions source4/torture/smb2/oplock.c
Original file line number Diff line number Diff line change
Expand Up @@ -4491,6 +4491,189 @@ static bool test_smb2_kernel_oplocks4(struct torture_context *tctx,
return ret;
}

/**
* 1) create testfile with stream
* 2) open stream r/w with batch oplock -> batch oplock granted
* 3) open stream r/o with batch oplock
*
* Verify 3) does trigger an oplock break
**/
static bool test_smb2_kernel_oplocks5(struct torture_context *tctx,
struct smb2_tree *tree)
{
const char *fname = "test_kernel_oplock4.dat";
const char *sname = "test_kernel_oplock4.dat:foo";
NTSTATUS status;
bool ret = true;
struct smb2_create create;
struct smb2_handle h1 = {{0}}, h2 = {{0}};

tree->session->transport->oplock.handler = torture_oplock_handler;
tree->session->transport->oplock.private_data = tree;
ZERO_STRUCT(break_info);
smb2_util_unlink(tree, fname);

/* 1 */
status = torture_smb2_testfile(tree, fname, &h1);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"Error creating testfile\n");
smb2_util_close(tree, h1);
ZERO_STRUCT(h1);

ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_READ;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = sname;

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h1 = create.out.file.handle;
smb2_util_close(tree, h1);
ZERO_STRUCT(h1);

/* 2 */
ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_ALL;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = sname;
create.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h1 = create.out.file.handle;

torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_BATCH, ret, done,
"Oplock level is not SMB2_OPLOCK_LEVEL_BATCH\n");

ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_READ;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = sname;
create.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h2 = create.out.file.handle;

torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_NONE, ret, done,
"Oplock level is not SMB2_OPLOCK_LEVEL_NONE\n");

torture_wait_for_oplock_break(tctx);
if (break_info.count != 1) {
torture_warning(tctx, "Stream open didn't cause oplock break\n");
}

done:
if (!smb2_util_handle_empty(h1)) {
smb2_util_close(tree, h1);
}
if (!smb2_util_handle_empty(h2)) {
smb2_util_close(tree, h2);
}
smb2_util_unlink(tree, fname);
return ret;
}

/**
* 1) create testfile with stream
* 2) 1st client opens stream r/w with batch oplock -> batch oplock granted
* 3) 2nd client opens stream r/o with batch oplock
*
* Verify 3) does trigger an oplock break
**/
static bool test_smb2_kernel_oplocks6(struct torture_context *tctx,
struct smb2_tree *tree,
struct smb2_tree *tree2)
{
const char *fname = "test_kernel_oplock6.dat";
const char *sname = "test_kernel_oplock6.dat:foo";
NTSTATUS status;
bool ret = true;
struct smb2_create create;
struct smb2_handle h1 = {{0}}, h2 = {{0}};

smb2_util_unlink(tree, fname);
status = torture_smb2_testfile(tree, fname, &h1);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"Error creating testfile\n");
smb2_util_close(tree, h1);
ZERO_STRUCT(h1);

tree->session->transport->oplock.handler = torture_oplock_handler;
tree->session->transport->oplock.private_data = tree;
ZERO_STRUCT(break_info);

/* 1 */
ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_READ;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = sname;

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h1 = create.out.file.handle;
smb2_util_close(tree, h1);
ZERO_STRUCT(h1);

/* 2 */
ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_ALL;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = fname;
create.in.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE;

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h1 = create.out.file.handle;

torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_EXCLUSIVE, ret, done,
"Oplock level is not SMB2_OPLOCK_LEVEL_EXCLUSIVE\n");

/* 3 */
ZERO_STRUCT(create);
create.in.desired_access = SEC_RIGHTS_FILE_READ;
create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
create.in.create_disposition = NTCREATEX_DISP_OPEN;
create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
create.in.fname = fname;

status = smb2_create(tree2, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "Error opening the file\n");
h2 = create.out.file.handle;

torture_assert_goto(tctx, create.out.oplock_level == SMB2_OPLOCK_LEVEL_NONE, ret, done,
"Oplock level is not SMB2_OPLOCK_LEVEL_NONE\n");

torture_wait_for_oplock_break(tctx);
torture_assert_goto(tctx, break_info.count == 1, ret, done, "Expected 1 oplock break\n");

done:
if (!smb2_util_handle_empty(h1)) {
smb2_util_close(tree, h1);
}
if (!smb2_util_handle_empty(h2)) {
smb2_util_close(tree, h2);
}
smb2_util_unlink(tree, fname);
return ret;
}

struct torture_suite *torture_smb2_kernel_oplocks_init(void)
{
struct torture_suite *suite =
Expand All @@ -4500,6 +4683,8 @@ struct torture_suite *torture_smb2_kernel_oplocks_init(void)
torture_suite_add_1smb2_test(suite, "kernel_oplocks2", test_smb2_kernel_oplocks2);
torture_suite_add_2smb2_test(suite, "kernel_oplocks3", test_smb2_kernel_oplocks3);
torture_suite_add_1smb2_test(suite, "kernel_oplocks4", test_smb2_kernel_oplocks4);
torture_suite_add_1smb2_test(suite, "kernel_oplocks5", test_smb2_kernel_oplocks5);
torture_suite_add_2smb2_test(suite, "kernel_oplocks6", test_smb2_kernel_oplocks6);

suite->description = talloc_strdup(suite, "SMB2-KERNEL-OPLOCK tests");

Expand Down

0 comments on commit 12c818b

Please sign in to comment.