summaryrefslogtreecommitdiffstats
path: root/source4/torture/smb2/maxfid.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/smb2/maxfid.c')
-rw-r--r--source4/torture/smb2/maxfid.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/source4/torture/smb2/maxfid.c b/source4/torture/smb2/maxfid.c
new file mode 100644
index 0000000..5f0b9fe
--- /dev/null
+++ b/source4/torture/smb2/maxfid.c
@@ -0,0 +1,149 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ SMB2 maxfid test
+
+ Copyright (C) Christof Schmitt 2016
+
+ 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 "torture/torture.h"
+#include "torture/smb2/proto.h"
+
+bool torture_smb2_maxfid(struct torture_context *tctx)
+{
+ bool ret = true;
+ NTSTATUS status;
+ struct smb2_tree *tree = NULL;
+ const char *dname = "smb2_maxfid";
+ size_t i, maxfid;
+ struct smb2_handle *handles, dir_handle = { };
+ size_t max_handles;
+
+ /*
+ * We limited this to 65520 as socket_wrapper has a limit of
+ * 65535 (0xfff0) open sockets.
+ *
+ * It could be increased by setting the following env variable:
+ *
+ * SOCKET_WRAPPER_MAX_SOCKETS=100000
+ */
+ max_handles = torture_setting_int(tctx, "maxopenfiles", 65520);
+
+ if (!torture_smb2_connection(tctx, &tree)) {
+ return false;
+ }
+
+ handles = talloc_array(tctx, struct smb2_handle, max_handles);
+ if (handles == 0) {
+ torture_fail(tctx, "Could not allocate handles array.\n");
+ return false;
+ }
+
+ smb2_deltree(tree, dname);
+
+ status = torture_smb2_testdir(tree, dname, &dir_handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "torture_smb2_testdir failed");
+ smb2_util_close(tree, dir_handle);
+
+ torture_comment(tctx, "Creating subdirectories\n");
+
+ for (i = 0; i < max_handles; i += 1000) {
+ char *name;
+ struct smb2_create create = { };
+ struct smb2_close close = { };
+
+ name = talloc_asprintf(tctx, "%s\\%zu", dname, i / 1000);
+ torture_assert_goto(tctx, (name != NULL), ret, done,
+ "no memory for directory name\n");
+
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create.in.fname = name;
+
+ status = smb2_create(tree, tctx, &create);
+ talloc_free(name);
+
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "CREATE directory failed\n");
+
+ close.in.file.handle = create.out.file.handle;
+ status = smb2_close(tree, &close);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "CLOSE directory failed\n");
+ }
+
+ torture_comment(tctx, "Testing maximum number of open files\n");
+
+ for (i = 0; i < max_handles; i++) {
+ char *name;
+ struct smb2_create create = { };
+
+ name = talloc_asprintf(tctx, "%s\\%zu\\%zu", dname, i / 1000, i);
+ torture_assert_goto(tctx, (name != NULL), ret, done,
+ "no memory for file name\n");
+
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = 0;
+ 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_CREATE;
+ create.in.fname = name;
+
+ status = smb2_create(tree, tctx, &create);
+ if (!NT_STATUS_IS_OK(status)) {
+ torture_comment(tctx, "create of %s failed: %s\n",
+ name, nt_errstr(status));
+ talloc_free(name);
+ break;
+ }
+ talloc_free(name);
+
+ handles[i] = create.out.file.handle;
+ }
+
+ maxfid = i;
+ if (maxfid == max_handles) {
+ torture_comment(tctx, "Reached test limit of %zu open files. "
+ "Adjust to higher test with "
+ "--option=torture:maxopenfiles=NNN\n", maxfid);
+ }
+
+ torture_comment(tctx, "Cleanup open files\n");
+
+ for (i = 0; i < maxfid; i++) {
+ status = smb2_util_close(tree, handles[i]);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "CLOSE failed\n");
+ }
+
+done:
+ smb2_deltree(tree, dname);
+ talloc_free(handles);
+
+ return ret;
+}