The Samba-Bugzilla – Attachment 16117 Details for
Bug 14430
smbd-notifyd O(n*n) performance issue with n watches registered for the same folder
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Fixed torture patch
patch.txt (text/plain), 9.02 KB, created by
Volker Lendecke
on 2020-07-07 12:35:27 UTC
(
hide
)
Description:
Fixed torture patch
Filename:
MIME Type:
Creator:
Volker Lendecke
Created:
2020-07-07 12:35:27 UTC
Size:
9.02 KB
patch
obsolete
>From be7e3536518bbb1234cef197eebd43d42d7a03b1 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 7 Jul 2020 09:25:20 +0200 >Subject: [PATCH] notify-bench4 > >--- > source3/torture/proto.h | 1 + > source3/torture/test_notify.c | 305 ++++++++++++++++++++++++++++++++++ > source3/torture/torture.c | 4 + > 3 files changed, 310 insertions(+) > >diff --git a/source3/torture/proto.h b/source3/torture/proto.h >index 18e686089ed..00fa113e6e2 100644 >--- a/source3/torture/proto.h >+++ b/source3/torture/proto.h >@@ -113,6 +113,7 @@ bool run_cleanup2(int dummy); > bool run_cleanup4(int dummy); > bool run_notify_bench2(int dummy); > bool run_notify_bench3(int dummy); >+bool run_notify_bench4(int dummy); > bool run_dbwrap_watch1(int dummy); > bool run_dbwrap_watch2(int dummy); > bool run_dbwrap_watch3(int dummy); >diff --git a/source3/torture/test_notify.c b/source3/torture/test_notify.c >index 33c2381fbbd..e6e7aa8c710 100644 >--- a/source3/torture/test_notify.c >+++ b/source3/torture/test_notify.c >@@ -726,3 +726,308 @@ bool run_notify_bench3(int dummy) > TALLOC_FREE(large); > return true; > } >+ >+struct notify_bench4_one_state { >+ struct tevent_context *ev; >+ struct cli_state *cli; >+ uint16_t dnum; >+}; >+ >+static void notify_bench4_one_opened(struct tevent_req *subreq); >+static void notify_bench4_one_notified(struct tevent_req *subreq); >+static void notify_bench4_one_echoed(struct tevent_req *subreq); >+ >+static struct tevent_req *notify_bench4_one_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ const char *dname) >+{ >+ struct tevent_req *req = NULL, *subreq = NULL; >+ struct notify_bench4_one_state *state = NULL; >+ >+ req = tevent_req_create(mem_ctx, &state, struct notify_bench4_one_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->ev = ev; >+ state->cli = cli; >+ >+ subreq = cli_ntcreate_send( >+ state, /* mem_ctx */ >+ ev, /* ev */ >+ cli, /* cli */ >+ dname, /* dname */ >+ 0, /* create_flags */ >+ SEC_FILE_READ_DATA| >+ SEC_FILE_READ_ATTRIBUTE, /* desired_access */ >+ 0, /* file_attributes */ >+ FILE_SHARE_READ| >+ FILE_SHARE_WRITE| >+ FILE_SHARE_DELETE, /* share_access */ >+ FILE_OPEN, /* create_disposition */ >+ FILE_DIRECTORY_FILE, /* create_options */ >+ SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level */ >+ 0); /* security_flags */ >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, notify_bench4_one_opened, req); >+ return req; >+} >+ >+static void notify_bench4_one_opened(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct notify_bench4_one_state *state = tevent_req_data( >+ req, struct notify_bench4_one_state); >+ NTSTATUS status; >+ >+ status = cli_ntcreate_recv(subreq, &state->dnum, NULL); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ >+ /* >+ * Hang the notify off long-running "cli", we don't want this >+ * to be cancelled when things are set up >+ */ >+ >+ subreq = cli_notify_send( >+ state->cli, /* mem_ctx */ >+ state->ev, /* ev */ >+ state->cli, /* cli */ >+ state->dnum, /* fnum */ >+ 32, /* buffer_size */ >+ FILE_NOTIFY_CHANGE_FILE_NAME| >+ FILE_NOTIFY_CHANGE_DIR_NAME| >+ FILE_NOTIFY_CHANGE_ATTRIBUTES| >+ FILE_NOTIFY_CHANGE_SIZE| >+ FILE_NOTIFY_CHANGE_LAST_WRITE| >+ FILE_NOTIFY_CHANGE_LAST_ACCESS| >+ FILE_NOTIFY_CHANGE_CREATION| >+ FILE_NOTIFY_CHANGE_SECURITY, /* completion_filter */ >+ false); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, notify_bench4_one_notified, req); >+ >+ /* >+ * Make sure the notify was delivered to the server >+ */ >+ subreq = cli_echo_send( >+ state, /* mem_ctx */ >+ state->ev, /* ev */ >+ state->cli, /* cli */ >+ 1, /* num_echos */ >+ (DATA_BLOB){0}); /* data */ >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, notify_bench4_one_echoed, req); >+} >+ >+static void notify_bench4_one_notified(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct notify_bench4_one_state *state = tevent_req_data( >+ req, struct notify_bench4_one_state); >+ uint32_t num_changes; >+ struct notify_change *changes = NULL; >+ NTSTATUS status; >+ >+ status = cli_notify_recv( >+ subreq, state, &num_changes, &changes); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ >+ printf("Got %"PRIu32" changes\n", num_changes); >+ >+ TALLOC_FREE(changes); >+ >+ tevent_req_done(req); >+} >+ >+static void notify_bench4_one_echoed(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ NTSTATUS status; >+ >+ status = cli_echo_recv(subreq); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(subreq, status)) { >+ return; >+ } >+ tevent_req_done(req); >+} >+ >+static NTSTATUS notify_bench4_one_recv(struct tevent_req *req, uint16_t *dnum) >+{ >+ struct notify_bench4_one_state *state = tevent_req_data( >+ req, struct notify_bench4_one_state); >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ return status; >+ } >+ *dnum = state->dnum; >+ return NT_STATUS_OK; >+} >+ >+struct notify_bench4_state { >+ struct tevent_req **reqs; >+ uint16_t *dnums; >+ size_t num_done; >+}; >+ >+static void notify_bench4_done(struct tevent_req *subreq); >+ >+static struct tevent_req *notify_bench4_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ const char *dname, >+ size_t num_ops) >+{ >+ struct tevent_req *req = NULL; >+ struct notify_bench4_state *state = NULL; >+ size_t i; >+ >+ req = tevent_req_create(mem_ctx, &state, struct notify_bench4_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->reqs = talloc_zero_array(state, struct tevent_req *, num_ops); >+ if (tevent_req_nomem(state->reqs, req)) { >+ return tevent_req_post(req, ev); >+ } >+ state->dnums = talloc_array(state, uint16_t, num_ops); >+ if (tevent_req_nomem(state->dnums, req)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ for (i=0; i<num_ops; i++) { >+ state->reqs[i] = notify_bench4_one_send( >+ state->reqs, ev, cli, dname); >+ if (tevent_req_nomem(state->reqs[i], req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback( >+ state->reqs[i], notify_bench4_done, req); >+ } >+ >+ return req; >+} >+ >+static void notify_bench4_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct notify_bench4_state *state = tevent_req_data( >+ req, struct notify_bench4_state); >+ size_t num_ops = talloc_array_length(state->reqs); >+ size_t i; >+ NTSTATUS status; >+ >+ for (i=0; i<num_ops; i++) { >+ if (state->reqs[i] == subreq) { >+ break; >+ } >+ } >+ if (i == num_ops) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return; >+ } >+ >+ status = notify_bench4_one_recv(subreq, &state->dnums[i]); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ >+ state->num_done += 1; >+ >+ if (state->num_done == num_ops) { >+ tevent_req_done(req); >+ } >+} >+ >+static NTSTATUS notify_bench4_recv( >+ struct tevent_req *req, TALLOC_CTX *mem_ctx, uint16_t **dnums) >+{ >+ struct notify_bench4_state *state = tevent_req_data( >+ req, struct notify_bench4_state); >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ return status; >+ } >+ *dnums = talloc_move(mem_ctx, &state->dnums); >+ return NT_STATUS_OK; >+} >+ >+bool run_notify_bench4(int dummy) >+{ >+ const char dname[] = "\\notify.dir\\subdir"; >+ struct cli_state *cli = NULL; >+ struct tevent_context *ev = NULL; >+ struct tevent_req *req = NULL; >+ uint16_t *dnums = NULL; >+ NTSTATUS status; >+ bool ok; >+ >+ printf("Starting to open many notifies on one directory\n"); >+ >+ if (!torture_open_connection_flags(&cli, 0, 0)) { >+ return false; >+ } >+ >+ cli_rmdir(cli, dname); >+ cli_rmdir(cli, "\\notify.dir"); >+ >+ status = cli_mkdir(cli, "\\notify.dir"); >+ if (!NT_STATUS_IS_OK(status)) { >+ printf("mkdir failed : %s\n", nt_errstr(status)); >+ return false; >+ } >+ status = cli_mkdir(cli, dname); >+ if (!NT_STATUS_IS_OK(status)) { >+ printf("mkdir failed : %s\n", nt_errstr(status)); >+ return false; >+ } >+ >+ ev = samba_tevent_context_init(talloc_tos()); >+ if (ev == NULL) { >+ printf("tevent_context_create failed\n"); >+ return false; >+ } >+ >+ req = notify_bench4_send(ev, ev, cli, dname, torture_numops); >+ if (req == 0) { >+ printf("notify_bench4_send failed\n"); >+ return false; >+ } >+ >+ ok = tevent_req_poll_ntstatus(req, ev, &status); >+ if (!ok) { >+ printf("tevent_req_poll_ntstatus failed: %s\n", >+ nt_errstr(status)); >+ return false; >+ } >+ >+ status = notify_bench4_recv(req, ev, &dnums); >+ if (!NT_STATUS_IS_OK(status)) { >+ printf("notify_bench4_recv failed: %s\n", nt_errstr(status)); >+ return false; >+ } >+ >+ system("/bin/sleep 9999"); >+ >+ return false; >+} >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index 2a3133373e9..7083ec6b3a6 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -14787,6 +14787,10 @@ static struct { > .name = "NOTIFY-BENCH3", > .fn = run_notify_bench3, > }, >+ { >+ .name = "NOTIFY-BENCH4", >+ .fn = run_notify_bench4, >+ }, > { > .name = "BAD-NBT-SESSION", > .fn = run_bad_nbt_session, >-- >2.20.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 14430
:
16109
|
16115
|
16116
| 16117 |
16118
|
18372
|
18373
|
18374
|
18455