2 Unix SMB/CIFS implementation.
6 Copyright (C) Christof Schmitt 2016
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
29 bool torture_smb2_maxfid(struct torture_context *tctx)
33 struct smb2_tree *tree = NULL;
34 const char *dname = "smb2_maxfid";
36 struct smb2_handle *handles, dir_handle = { };
39 max_handles = torture_setting_int(tctx, "maxopenfiles", 0x11000);
41 if (!torture_smb2_connection(tctx, &tree)) {
45 handles = talloc_array(tctx, struct smb2_handle, max_handles);
47 torture_fail(tctx, "Could not allocate handles array.\n");
51 smb2_deltree(tree, dname);
53 status = torture_smb2_testdir(tree, dname, &dir_handle);
54 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
55 "torture_smb2_testdir failed");
56 smb2_util_close(tree, dir_handle);
58 torture_comment(tctx, "Creating subdirectories\n");
60 for (i = 0; i < max_handles; i += 1000) {
62 struct smb2_create create = { };
63 struct smb2_close close = { };
65 name = talloc_asprintf(tctx, "%s\\%zu", dname, i / 1000);
66 torture_assert_goto(tctx, (name != NULL), ret, done,
67 "no memory for directory name\n");
69 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
70 create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
71 create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
72 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
73 NTCREATEX_SHARE_ACCESS_WRITE |
74 NTCREATEX_SHARE_ACCESS_DELETE;
75 create.in.create_disposition = NTCREATEX_DISP_CREATE;
76 create.in.fname = name;
78 status = smb2_create(tree, tctx, &create);
81 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
82 "CREATE directory failed\n");
84 close.in.file.handle = create.out.file.handle;
85 status = smb2_close(tree, &close);
86 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
87 "CLOSE directory failed\n");
90 torture_comment(tctx, "Testing maximum number of open files\n");
92 for (i = 0; i < max_handles; i++) {
94 struct smb2_create create = { };
96 name = talloc_asprintf(tctx, "%s\\%zu\\%zu", dname, i / 1000, i);
97 torture_assert_goto(tctx, (name != NULL), ret, done,
98 "no memory for file name\n");
100 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
101 create.in.create_options = 0;
102 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
103 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
104 NTCREATEX_SHARE_ACCESS_WRITE |
105 NTCREATEX_SHARE_ACCESS_DELETE;
106 create.in.create_disposition = NTCREATEX_DISP_CREATE;
107 create.in.fname = name;
109 status = smb2_create(tree, tctx, &create);
110 if (!NT_STATUS_IS_OK(status)) {
111 torture_comment(tctx, "create of %s failed: %s\n",
112 name, nt_errstr(status));
118 handles[i] = create.out.file.handle;
122 if (maxfid == max_handles) {
123 torture_comment(tctx, "Reached test limit of %zu open files. "
124 "Adjust to higher test with "
125 "--option=torture:maxopenfiles=NNN\n", maxfid);
128 torture_comment(tctx, "Cleanup open files\n");
130 for (i = 0; i < maxfid; i++) {
131 union smb_setfileinfo sfinfo = { };
133 sfinfo.disposition_info.in.delete_on_close = 1;
134 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
135 sfinfo.generic.in.file.handle = handles[i];
137 status = smb2_setinfo_file(tree, &sfinfo);
138 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
141 status = smb2_util_close(tree, handles[i]);
142 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
147 smb2_deltree(tree, dname);
148 talloc_free(handles);