[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Jun 1 08:15:02 UTC 2023


The branch, master has been updated
       via  5303f6f7fd1 s4:torture/smb2: add smb2.bench.read test
       via  56488363862 s4:torture/smb2: add --option="torture:looplimit=150000" to smb2.bench.echo
       via  d01db89d905 s4:torture/smb2: move benchmarking tests to bench.c
       via  e03ccb5b12b smb2_negprot: add CALLGRIND_START_INSTRUMENTATION after SMB2 negprot
       via  77c925681dc lib/replace: check for valgrind/callgrind.h
       via  bfb1494e818 lib/util: use RUNNING_ON_VALGRIND to check if valgrind is used
       via  be5e4d164df smb2_server: use MSG_DONTWAIT to get non-blocking send/recvmsg
       via  6e848f9d22f s3:smbd: only do profiling overhead in smbd_tevent_trace_callback() when needed
       via  ff259bd1b70 smbprofile: add smbprofile_active() helper
       via  a08f8b2a2cc smb2_server: optimize SMB2_OP_KEEPALIVE (SMB2 Echo)
      from  9aa440d52d7 s4-rpc_server: Filter via dsdb_dc_functional_level() before we are returning a lookup directly

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5303f6f7fd1ddccdfa6b752b20f712237850527c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Sep 22 15:49:41 2022 +0200

    s4:torture/smb2: add smb2.bench.read test
    
    This test opens one file for each loop (for nprocs * qdepth loops)
    and for each file it loops in read requests for the first
    io_size bytes.
    
    time smbtorture //127.0.0.1/m -Uroot%test smb2.bench.read \
            --option="torture:timelimit=600" \
            --option="torture:nprocs=1" \
            --option="torture:qdepth=4" \
            --option="torture:io_size=4096"
    
    In order to generate constant load for profiles
    --option="torture:looplimit=150000" can be used to stop
    after the given number of loops before the timelimit hits.
    
    Sometimes the bottleneck is the smbtorture process.
    In order to bring the smbd process to 100% cpu, you can use
    '--option="libsmb:client_guid=6112f7d3-9528-4a2a-8861-0ca129aae6c4"'
    and run multiple instances of the test at the same time,
    which both talk to the same smbd process.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Thu Jun  1 08:14:23 UTC 2023 on atb-devel-224

commit 56488363862aeeeacbdd675c09603c5624675d2b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Apr 28 08:02:39 2023 +0000

    s4:torture/smb2: add --option="torture:looplimit=150000" to smb2.bench.echo
    
    Also see the commit message of 23988f19e7cc2823d6c0c0f40af0195d0a3b81bf
    for other examples...
    
    This test calls SMB2_Echo in a loop per connection.
    
    time smbtorture //127.0.0.1/m -Uroot%test smb2.bench.echo \
            --option="torture:timelimit=600" \
            --option="torture:looplimit=150000" \
            --option="torture:nprocs=1" \
            --option="torture:qdepth=1"
    
    This is a very useful test to show how many requests are possible
    at the raw SMB2 layer.
    
    In order to do profiling and being able to compare the
    profiles between runs, it is important to produce the
    exact same load in each run, which is not possible
    with the typical --option="torture:timelimit=600".
    
    E.g. when the server runs under 'valgrind --tool=callgrind bin/smbd'
    I typically run without "torture:looplimit" first in order to
    see, which rate is possible per second, then I'll add a
    "torture:looplimit" in order to run about half of the timelimit.
    Then the looplimit should run for some time, but finish
    before the timelimit.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit d01db89d905eb85b014e2d9b701a507d41cd2dff
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Sep 22 15:02:04 2022 +0200

    s4:torture/smb2: move benchmarking tests to bench.c
    
    I'll add more tests there soon
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit e03ccb5b12bca8588baca70c4d45702833c7bdd5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Apr 25 15:38:30 2023 +0000

    smb2_negprot: add CALLGRIND_START_INSTRUMENTATION after SMB2 negprot
    
    This allows us to support starting smbd under callgrind and only start
    the overhead and instrumentation after the SMB2 negprot, this allows us
    to profile only useful stuff and not all the smbd startup, forking and
    multichannel handling.
    
    This will do the trick:
    
      valgrind --tool=callgrind --instr-atstart=no smbd
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 77c925681dc964adc67aa866ae47149dabd576e9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 31 12:59:47 2023 +0200

    lib/replace: check for valgrind/callgrind.h
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit bfb1494e818a8ec1743c50a938e6475771d0a52f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed May 31 12:09:09 2023 +0200

    lib/util: use RUNNING_ON_VALGRIND to check if valgrind is used
    
    We should not skip all of close_low_fd() just because we
    detected valgrind headers at build time.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit be5e4d164df6dbfca391f46ad99350e3b72c311b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 30 23:43:37 2020 +0200

    smb2_server: use MSG_DONTWAIT to get non-blocking send/recvmsg
    
    It means we can make the fd blocking, which will help
    with io_uring support.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 6e848f9d22ff32788a9544d937119a987c50cb9b
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Apr 26 17:22:01 2023 +0200

    s3:smbd: only do profiling overhead in smbd_tevent_trace_callback() when needed
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit ff259bd1b70737a5b0ff31e33db4a18837c40e89
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Apr 26 17:21:38 2023 +0200

    smbprofile: add smbprofile_active() helper
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a08f8b2a2cc1ba8f7246375d2d697ce979281402
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 14 13:45:26 2023 +0000

    smb2_server: optimize SMB2_OP_KEEPALIVE (SMB2 Echo)
    
    This is not strictly needed, but it helps profiling
    the core smb2_server.c code with the 'smb2.bench.echo'
    test.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/replace/wscript                |    2 +-
 lib/util/close_low_fd.c            |   14 +-
 source3/include/smbprofile.h       |   10 +
 source3/smbd/smb2_negprot.c        |   16 +
 source3/smbd/smb2_process.c        |   51 +-
 source3/smbd/smb2_server.c         |   37 +-
 source4/torture/smb2/bench.c       | 1376 ++++++++++++++++++++++++++++++++++++
 source4/torture/smb2/create.c      |  813 ---------------------
 source4/torture/smb2/wscript_build |    1 +
 9 files changed, 1494 insertions(+), 826 deletions(-)
 create mode 100644 source4/torture/smb2/bench.c


Changeset truncated at 500 lines:

diff --git a/lib/replace/wscript b/lib/replace/wscript
index d6625817e02..f5c597c04c2 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -114,7 +114,7 @@ def configure(conf):
     conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h')
 
     conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h')
-    conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h')
+    conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h valgrind/callgrind.h')
     conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h')
     conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h')
     conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h')
diff --git a/lib/util/close_low_fd.c b/lib/util/close_low_fd.c
index 5e749187113..84a69067644 100644
--- a/lib/util/close_low_fd.c
+++ b/lib/util/close_low_fd.c
@@ -21,11 +21,22 @@
 #include "system/filesys.h"
 #include "close_low_fd.h"
 
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#elif defined(HAVE_VALGRIND_H)
+#include <valgrind.h>
+#else
+#define RUNNING_ON_VALGRIND 0
+#endif
+
 _PUBLIC_ int close_low_fd(int fd)
 {
-#ifndef VALGRIND
 	int ret, dev_null;
 
+	if (RUNNING_ON_VALGRIND) {
+		return 0;
+	}
+
 	dev_null = open("/dev/null", O_RDWR, 0);
 
 	if ((dev_null == -1) && (errno == ENFILE)) {
@@ -60,6 +71,5 @@ _PUBLIC_ int close_low_fd(int fd)
 		return err;
 	}
 	close(dev_null);
-#endif
 	return 0;
 }
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index ce7a7405bf4..7b080e11ee1 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -497,6 +497,11 @@ static inline void smbprofile_dump_schedule(void)
 	smbprofile_dump_schedule_timer();
 }
 
+static inline bool smbprofile_active(void)
+{
+	return smbprofile_state.config.do_count;
+}
+
 static inline bool smbprofile_dump_pending(void)
 {
 	if (smbprofile_state.internal.te == NULL) {
@@ -574,6 +579,11 @@ static inline uint64_t profile_timestamp(void)
 
 #define PROFILE_TIMESTAMP(x) (*(x)=(struct timespec){0})
 
+static inline bool smbprofile_active(void)
+{
+	return false;
+}
+
 static inline bool smbprofile_dump_pending(void)
 {
 	return false;
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 408faf1481d..c13f472c4e9 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -30,6 +30,9 @@
 #include "auth/gensec/gensec.h"
 #include "lib/util/string_wrappers.h"
 #include "source3/lib/substitute.h"
+#ifdef HAVE_VALGRIND_CALLGRIND_H
+#include <valgrind/callgrind.h>
+#endif /* HAVE_VALGRIND_CALLGRIND_H */
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_SMB2
@@ -914,6 +917,19 @@ static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
 	 */
 	status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
 	if (NT_STATUS_IS_OK(status)) {
+		/*
+		 * This allows us to support starting smbd under
+		 * callgrind and only start the overhead and
+		 * instrumentation after the SMB2 negprot,
+		 * this allows us to profile only useful
+		 * stuff and not all the smbd startup, forking
+		 * and multichannel handling.
+		 *
+		 * valgrind --tool=callgrind --instr-atstart=no smbd
+		 */
+#ifdef CALLGRIND_START_INSTRUMENTATION
+		CALLGRIND_START_INSTRUMENTATION;
+#endif
 		return;
 	}
 
diff --git a/source3/smbd/smb2_process.c b/source3/smbd/smb2_process.c
index ad4386e08a4..e0c4cd459c1 100644
--- a/source3/smbd/smb2_process.c
+++ b/source3/smbd/smb2_process.c
@@ -1697,12 +1697,47 @@ struct smbd_tevent_trace_state {
 	SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
 };
 
+static inline void smbd_tevent_trace_callback_before_loop_once(
+	struct smbd_tevent_trace_state *state)
+{
+	talloc_free(state->frame);
+	state->frame = talloc_stackframe_pool(8192);
+}
+
+static inline void smbd_tevent_trace_callback_after_loop_once(
+	struct smbd_tevent_trace_state *state)
+{
+	TALLOC_FREE(state->frame);
+}
+
 static void smbd_tevent_trace_callback(enum tevent_trace_point point,
 				       void *private_data)
 {
 	struct smbd_tevent_trace_state *state =
 		(struct smbd_tevent_trace_state *)private_data;
 
+	switch (point) {
+	case TEVENT_TRACE_BEFORE_WAIT:
+		break;
+	case TEVENT_TRACE_AFTER_WAIT:
+		break;
+	case TEVENT_TRACE_BEFORE_LOOP_ONCE:
+		smbd_tevent_trace_callback_before_loop_once(state);
+		break;
+	case TEVENT_TRACE_AFTER_LOOP_ONCE:
+		smbd_tevent_trace_callback_after_loop_once(state);
+		break;
+	}
+
+	errno = 0;
+}
+
+static void smbd_tevent_trace_callback_profile(enum tevent_trace_point point,
+					       void *private_data)
+{
+	struct smbd_tevent_trace_state *state =
+		(struct smbd_tevent_trace_state *)private_data;
+
 	switch (point) {
 	case TEVENT_TRACE_BEFORE_WAIT:
 		if (!smbprofile_dump_pending()) {
@@ -1732,11 +1767,10 @@ static void smbd_tevent_trace_callback(enum tevent_trace_point point,
 		}
 		break;
 	case TEVENT_TRACE_BEFORE_LOOP_ONCE:
-		TALLOC_FREE(state->frame);
-		state->frame = talloc_stackframe_pool(8192);
+		smbd_tevent_trace_callback_before_loop_once(state);
 		break;
 	case TEVENT_TRACE_AFTER_LOOP_ONCE:
-		TALLOC_FREE(state->frame);
+		smbd_tevent_trace_callback_after_loop_once(state);
 		break;
 	}
 
@@ -2009,8 +2043,15 @@ void smbd_process(struct tevent_context *ev_ctx,
 
 	TALLOC_FREE(trace_state.frame);
 
-	tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
-				  &trace_state);
+	if (smbprofile_active()) {
+		tevent_set_trace_callback(ev_ctx,
+					  smbd_tevent_trace_callback_profile,
+					  &trace_state);
+	} else {
+		tevent_set_trace_callback(ev_ctx,
+					  smbd_tevent_trace_callback,
+					  &trace_state);
+	}
 
 	ret = tevent_loop_wait(ev_ctx);
 	if (ret != 0) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 39d0e80f591..462e0d7ecac 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -135,7 +135,6 @@ static const struct smbd_smb2_dispatch_table {
 		.as_root = true,
 	},{
 		.opcode = SMB2_OP_KEEPALIVE,
-		.as_root = true,
 	},{
 		.opcode = SMB2_OP_QUERY_DIRECTORY,
 		.need_session = true,
@@ -325,11 +324,23 @@ static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
 	}
 	tevent_fd_set_auto_close(xconn->transport.fde);
 
-	/* Ensure child is set to non-blocking mode */
+	/*
+	 * Ensure child is set to non-blocking mode,
+	 * unless the system supports MSG_DONTWAIT,
+	 * if MSG_DONTWAIT is available we should force
+	 * blocking mode.
+	 */
+#ifdef MSG_DONTWAIT
+	rc = set_blocking(xconn->transport.sock, true);
+	if (rc < 0) {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+#else
 	rc = set_blocking(xconn->transport.sock, false);
 	if (rc < 0) {
 		return NT_STATUS_INTERNAL_ERROR;
 	}
+#endif
 
 	return NT_STATUS_OK;
 }
@@ -3415,7 +3426,7 @@ skipped_signing:
 		SMB_ASSERT(call->fileid_ofs == 0);
 		/* This call needs to be run as root */
 		change_to_root_user();
-	} else {
+	} else if (opcode != SMB2_OP_KEEPALIVE) {
 		SMB_ASSERT(call->need_tcon);
 	}
 
@@ -4729,6 +4740,7 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
 
 	while (xconn->smb2.send_queue != NULL) {
 		struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
+		unsigned sendmsg_flags = 0;
 		bool ok;
 		struct msghdr msg;
 
@@ -4802,7 +4814,14 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
 			.msg_iovlen = e->count,
 		};
 
-		ret = sendmsg(xconn->transport.sock, &msg, 0);
+#ifdef MSG_NOSIGNAL
+		sendmsg_flags |= MSG_NOSIGNAL;
+#endif
+#ifdef MSG_DONTWAIT
+		sendmsg_flags |= MSG_DONTWAIT;
+#endif
+
+		ret = sendmsg(xconn->transport.sock, &msg, sendmsg_flags);
 		if (ret == 0) {
 			/* propagate end of file */
 			return NT_STATUS_INTERNAL_ERROR;
@@ -4865,6 +4884,7 @@ static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
 	struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
 	struct smbd_smb2_request *req = NULL;
 	size_t min_recvfile_size = UINT32_MAX;
+	unsigned recvmsg_flags = 0;
 	int ret;
 	int err;
 	bool retry;
@@ -4910,7 +4930,14 @@ again:
 		.msg_iovlen = 1,
 	};
 
-	ret = recvmsg(xconn->transport.sock, &msg, 0);
+#ifdef MSG_NOSIGNAL
+	recvmsg_flags |= MSG_NOSIGNAL;
+#endif
+#ifdef MSG_DONTWAIT
+	recvmsg_flags |= MSG_DONTWAIT;
+#endif
+
+	ret = recvmsg(xconn->transport.sock, &msg, recvmsg_flags);
 	if (ret == 0) {
 		/* propagate end of file */
 		status = NT_STATUS_END_OF_FILE;
diff --git a/source4/torture/smb2/bench.c b/source4/torture/smb2/bench.c
new file mode 100644
index 00000000000..a91ca6c08d3
--- /dev/null
+++ b/source4/torture/smb2/bench.c
@@ -0,0 +1,1376 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   SMB2 bench test suite
+
+   Copyright (C) Stefan Metzmacher 2022
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "libcli/smb/smbXcli_base.h"
+#include "torture/torture.h"
+#include "torture/util.h"
+#include "torture/smb2/proto.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/security/security.h"
+
+#include "system/filesys.h"
+#include "auth/credentials/credentials.h"
+#include "lib/cmdline/cmdline.h"
+#include "librpc/gen_ndr/security.h"
+#include "lib/events/events.h"
+
+#define FNAME "test_create.dat"
+#define DNAME "smb2_open"
+
+#define CHECK_STATUS(status, correct) do { \
+	if (!NT_STATUS_EQUAL(status, correct)) { \
+		torture_result(tctx, TORTURE_FAIL, \
+			"(%s) Incorrect status %s - should be %s\n", \
+			 __location__, nt_errstr(status), nt_errstr(correct)); \
+		return false; \
+	}} while (0)
+
+#define CHECK_EQUAL(v, correct) do { \
+	if (v != correct) { \
+		torture_result(tctx, TORTURE_FAIL, \
+			"(%s) Incorrect value for %s 0x%08llx - " \
+		        "should be 0x%08llx\n", \
+			 __location__, #v, \
+		        (unsigned long long)v, \
+		        (unsigned long long)correct); \
+		return false;					\
+	}} while (0)
+
+#define CHECK_TIME(t, field) do { \
+	time_t t1, t2; \
+	finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
+	finfo.all_info.in.file.handle = h1; \
+	status = smb2_getinfo_file(tree, tctx, &finfo); \
+	CHECK_STATUS(status, NT_STATUS_OK); \
+	t1 = t & ~1; \
+	t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
+	if (abs(t1-t2) > 2) { \
+		torture_result(tctx, TORTURE_FAIL, \
+			"(%s) wrong time for field %s  %s - %s\n", \
+			__location__, #field, \
+			timestring(tctx, t1), \
+			timestring(tctx, t2)); \
+		dump_all_info(tctx, &finfo); \
+		ret = false; \
+	}} while (0)
+
+#define CHECK_NTTIME(t, field) do { \
+	NTTIME t2; \
+	finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
+	finfo.all_info.in.file.handle = h1; \
+	status = smb2_getinfo_file(tree, tctx, &finfo); \
+	CHECK_STATUS(status, NT_STATUS_OK); \
+	t2 = finfo.all_info.out.field; \
+	if (llabs((int64_t)(t-t2)) > 20000) { \
+		torture_result(tctx, TORTURE_FAIL, \
+			"(%s) wrong time for field %s  %s - %s\n", \
+		       __location__, #field, \
+		       nt_time_string(tctx, t), \
+		       nt_time_string(tctx, t2)); \
+		dump_all_info(tctx, &finfo); \
+		ret = false; \
+	}} while (0)
+
+#define CHECK_ALL_INFO(v, field) do { \
+	finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
+	finfo.all_info.in.file.handle = h1; \
+	status = smb2_getinfo_file(tree, tctx, &finfo); \
+	CHECK_STATUS(status, NT_STATUS_OK); \
+	if ((v) != (finfo.all_info.out.field)) { \
+	       torture_result(tctx, TORTURE_FAIL, \
+			"(%s) wrong value for field %s  0x%x - 0x%x\n", \
+			__location__, #field, (int)v,\
+			(int)(finfo.all_info.out.field)); \
+		dump_all_info(tctx, &finfo); \
+		ret = false; \
+	}} while (0)
+
+#define CHECK_VAL(v, correct) do { \
+	if ((v) != (correct)) { \
+		torture_result(tctx, TORTURE_FAIL, \
+			"(%s) wrong value for %s  0x%x - should be 0x%x\n", \
+		       __location__, #v, (int)(v), (int)correct); \
+		ret = false; \
+	}} while (0)
+
+#define SET_ATTRIB(sattrib) do { \
+	union smb_setfileinfo sfinfo; \
+	ZERO_STRUCT(sfinfo.basic_info.in); \
+	sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
+	sfinfo.basic_info.in.file.handle = h1; \
+	sfinfo.basic_info.in.attrib = sattrib; \
+	status = smb2_setinfo_file(tree, &sfinfo); \
+	if (!NT_STATUS_IS_OK(status)) { \
+		torture_comment(tctx, \
+		    "(%s) Failed to set attrib 0x%x on %s\n", \
+		       __location__, (unsigned int)(sattrib), fname); \
+	}} while (0)
+
+/*
+   stress testing keepalive iops
+ */
+
+struct test_smb2_bench_echo_conn;
+struct test_smb2_bench_echo_loop;
+
+struct test_smb2_bench_echo_state {
+	struct torture_context *tctx;
+	size_t num_conns;
+	struct test_smb2_bench_echo_conn *conns;
+	size_t num_loops;
+	struct test_smb2_bench_echo_loop *loops;
+	size_t pending_loops;
+	struct timeval starttime;
+	int timecount;
+	int timelimit;
+	uint64_t num_finished;
+	double total_latency;
+	double min_latency;
+	double max_latency;
+	bool ok;
+	bool stop;
+};
+
+struct test_smb2_bench_echo_conn {
+	struct test_smb2_bench_echo_state *state;
+	int idx;
+	struct smb2_tree *tree;
+};
+
+struct test_smb2_bench_echo_loop {
+	struct test_smb2_bench_echo_state *state;
+	struct test_smb2_bench_echo_conn *conn;
+	int idx;
+	struct tevent_immediate *im;
+	struct tevent_req *req;
+	struct timeval starttime;
+	uint64_t num_started;
+	uint64_t num_finished;
+	uint64_t total_finished;
+	uint64_t max_finished;
+	double total_latency;
+	double min_latency;
+	double max_latency;
+	NTSTATUS error;
+};
+
+static void test_smb2_bench_echo_loop_do(
+	struct test_smb2_bench_echo_loop *loop);
+
+static void test_smb2_bench_echo_loop_start(struct tevent_context *ctx,
+						       struct tevent_immediate *im,
+						       void *private_data)
+{
+	struct test_smb2_bench_echo_loop *loop =
+		(struct test_smb2_bench_echo_loop *)
+		private_data;
+
+	test_smb2_bench_echo_loop_do(loop);
+}
+
+static void test_smb2_bench_echo_loop_done(struct tevent_req *req);
+
+static void test_smb2_bench_echo_loop_do(
+	struct test_smb2_bench_echo_loop *loop)
+{
+	struct test_smb2_bench_echo_state *state = loop->state;
+
+	loop->num_started += 1;
+	loop->starttime = timeval_current();
+	loop->req = smb2cli_echo_send(state->loops,
+				      state->tctx->ev,
+				      loop->conn->tree->session->transport->conn,
+				      1000);
+	torture_assert_goto(state->tctx, loop->req != NULL,
+			    state->ok, asserted, "smb2cli_echo_send");


-- 
Samba Shared Repository



More information about the samba-cvs mailing list