diff options
author | Ralph Boehme <slow@samba.org> | 2017-07-13 16:05:49 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2017-08-26 05:05:08 +0200 |
commit | 51f40a0e1d10069f55a5884ff1579e8f15f10a1e (patch) | |
tree | 89b6934a56229d1effd3de69a34420f91073cf63 | |
parent | 71a68d22a15d12c4038026dd065c54721ddc6723 (diff) | |
download | samba-51f40a0e1d10069f55a5884ff1579e8f15f10a1e.tar.gz |
s4/torture: add a test for rename change notification with inotify enabled
This is already fixed in master by
5eccc2fd0072409f166c63e6876266f926411423~10..5eccc2fd0072409f166c63e6876266f926411423.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=12903
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Aug 26 05:05:08 CEST 2017 on sn-devel-144
-rw-r--r-- | source4/torture/smb2/notify.c | 158 | ||||
-rw-r--r-- | source4/torture/smb2/smb2.c | 1 |
2 files changed, 159 insertions, 0 deletions
diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c index 9fc856cd1a4..6ef24fe889e 100644 --- a/source4/torture/smb2/notify.c +++ b/source4/torture/smb2/notify.c @@ -2354,6 +2354,151 @@ static bool torture_smb2_notify_rmdir4(struct torture_context *torture, return torture_smb2_notify_rmdir(torture, tree1, tree2, true); } +static void notify_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + struct smb2_request *req = talloc_get_type_abort( + private_data, struct smb2_request); + + smb2_cancel(req); +} + +static bool torture_smb2_inotify_rename(struct torture_context *torture, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + NTSTATUS status; + struct smb2_notify notify; + struct notify_changes change1 = {0}; + struct notify_changes change2 = {0}; + struct smb2_create create; + union smb_setfileinfo sinfo; + struct smb2_handle h1 = {{0}}; + struct smb2_handle h2 = {{0}}; + struct smb2_request *req; + struct tevent_timer *te = NULL; + bool ok = false; + + smb2_deltree(tree1, BASEDIR); + + torture_comment(torture, "Testing change notify of a rename with inotify\n"); + + status = torture_smb2_testdir(tree1, BASEDIR, &h1); + torture_assert_ntstatus_ok_goto(torture, status, ok, done, "torture_smb2_testdir failed"); + + ZERO_STRUCT(create); + create.in.desired_access = SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE| + SEC_RIGHTS_FILE_ALL; + create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + create.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = BASEDIR "\\subdir-name"; + + status = smb2_create(tree2, torture, &create); + torture_assert_ntstatus_ok_goto(torture, status, ok, done, "smb2_create failed\n"); + h2 = create.out.file.handle; + + ZERO_STRUCT(notify); + notify.level = RAW_NOTIFY_SMB2; + notify.in.buffer_size = 4096; + notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.in.file.handle = h1; + notify.in.recursive = true; + req = smb2_notify_send(tree1, ¬ify); + torture_assert_not_null_goto(torture, req, ok, done, "smb2_notify_send failed\n"); + + while (!NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { + if (tevent_loop_once(torture->ev) != 0) { + return false; + } + } + + ZERO_STRUCT(sinfo); + sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; + sinfo.rename_information.in.file.handle = h2; + sinfo.rename_information.in.new_name = BASEDIR "\\subdir-name-r"; + + status = smb2_setinfo_file(tree2, &sinfo); + torture_assert_ntstatus_ok_goto(torture, status, ok, done, "smb2_setinfo_file failed\n"); + + smb2_util_close(tree2, h2); + + te = tevent_add_timer(torture->ev, + tree1, + tevent_timeval_current_ofs(1, 0), + notify_timeout, + req); + torture_assert_not_null_goto(torture, te, ok, done, "tevent_add_timer failed\n"); + + status = smb2_notify_recv(req, torture, ¬ify); + torture_assert_ntstatus_ok_goto(torture, status, ok, done, "smb2_notify_recv failed\n"); + + torture_assert_goto(torture, notify.out.num_changes == 1 || notify.out.num_changes == 2, + ok, done, "bad notify\n"); + + change1 = notify.out.changes[0]; + if (notify.out.num_changes == 2) { + change2 = notify.out.changes[1]; + } else { + /* + * We may only get one event at a time, so check for the + * matching second event for the oldname/newname or + * removed/added pair. + */ + ZERO_STRUCT(notify); + notify.level = RAW_NOTIFY_SMB2; + notify.in.buffer_size = 4096; + notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.in.file.handle = h1; + notify.in.recursive = true; + req = smb2_notify_send(tree1, ¬ify); + torture_assert_not_null_goto(torture, req, ok, done, "smb2_notify_send failed\n"); + + status = smb2_notify_recv(req, torture, ¬ify); + torture_assert_ntstatus_ok_goto(torture, status, ok, done, "smb2_notify_recv failed\n"); + + torture_assert_goto(torture, notify.out.num_changes == 1, ok, done, + "bad notify\n"); + + change2 = notify.out.changes[0]; + } + + if ((change1.action != NOTIFY_ACTION_OLD_NAME) && + (change1.action != NOTIFY_ACTION_REMOVED)) + { + torture_fail_goto(torture, done, "bad change notification\n"); + } + torture_assert_str_equal_goto(torture, change1.name.s, "subdir-name", + ok, done, "bad change notification\n"); + + if ((change2.action != NOTIFY_ACTION_NEW_NAME) && + (change2.action != NOTIFY_ACTION_ADDED)) + { + torture_fail_goto(torture, done, "bad change notification\n"); + } + torture_assert_str_equal_goto(torture, change2.name.s, "subdir-name-r", + ok, done, "bad change notification\n"); + + ok = true; +done: + if (!smb2_util_handle_empty(h1)) { + smb2_util_close(tree2, h1); + } + if (!smb2_util_handle_empty(h2)) { + smb2_util_close(tree2, h2); + } + + smb2_deltree(tree1, BASEDIR); + return ok; +} + /* basic testing of SMB2 change notify */ @@ -2393,3 +2538,16 @@ struct torture_suite *torture_smb2_notify_init(TALLOC_CTX *ctx) return suite; } +/* + basic testing of SMB2 change notify +*/ +struct torture_suite *torture_smb2_notify_inotify_init(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "notify-inotify"); + + suite->description = talloc_strdup(suite, "SMB2-NOTIFY tests that use inotify"); + + torture_suite_add_2smb2_test(suite, "inotify-rename", torture_smb2_inotify_rename); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 352a36e2962..344cf5a40a5 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -155,6 +155,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) torture_suite_add_suite(suite, torture_smb2_create_init(suite)); torture_suite_add_suite(suite, torture_smb2_acls_init(suite)); torture_suite_add_suite(suite, torture_smb2_notify_init(suite)); + torture_suite_add_suite(suite, torture_smb2_notify_inotify_init(suite)); torture_suite_add_suite(suite, torture_smb2_notify_disabled_init(suite)); torture_suite_add_suite(suite, torture_smb2_durable_open_init(suite)); |