s4:torture: Use 65520 for maxopenfiles
[samba.git] / source4 / torture / smb2 / maxfid.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    SMB2 maxfid test
5
6    Copyright (C) Christof Schmitt 2016
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28
29 bool torture_smb2_maxfid(struct torture_context *tctx)
30 {
31         bool ret = true;
32         NTSTATUS status;
33         struct smb2_tree *tree = NULL;
34         const char *dname = "smb2_maxfid";
35         size_t i, maxfid;
36         struct smb2_handle *handles,  dir_handle = { };
37         size_t max_handles;
38
39         /*
40          * We limited this to 65520 as socket_wrapper has a limit of
41          * 65535 (0xfff0) open sockets.
42          *
43          * It could be increased by setting the following env variable:
44          *
45          * SOCKET_WRAPPER_MAX_SOCKETS=100000
46          */
47         max_handles = torture_setting_int(tctx, "maxopenfiles", 65520);
48
49         if (!torture_smb2_connection(tctx, &tree)) {
50                 return false;
51         }
52
53         handles = talloc_array(tctx, struct smb2_handle, max_handles);
54         if (handles == 0) {
55                 torture_fail(tctx, "Could not allocate handles array.\n");
56                 return false;
57         }
58
59         smb2_deltree(tree, dname);
60
61         status = torture_smb2_testdir(tree, dname, &dir_handle);
62         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
63                                         "torture_smb2_testdir failed");
64         smb2_util_close(tree, dir_handle);
65
66         torture_comment(tctx, "Creating subdirectories\n");
67
68         for (i = 0; i < max_handles; i += 1000) {
69                 char *name;
70                 struct smb2_create create = { };
71                 struct smb2_close close = { };
72
73                 name = talloc_asprintf(tctx, "%s\\%zu", dname, i / 1000);
74                 torture_assert_goto(tctx, (name != NULL), ret, done,
75                                     "no memory for directory name\n");
76
77                 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
78                 create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
79                 create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
80                 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
81                         NTCREATEX_SHARE_ACCESS_WRITE |
82                         NTCREATEX_SHARE_ACCESS_DELETE;
83                 create.in.create_disposition = NTCREATEX_DISP_CREATE;
84                 create.in.fname = name;
85
86                 status = smb2_create(tree, tctx, &create);
87                 talloc_free(name);
88
89                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
90                                                 "CREATE directory failed\n");
91
92                 close.in.file.handle = create.out.file.handle;
93                 status = smb2_close(tree, &close);
94                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
95                                                 "CLOSE directory failed\n");
96         }
97
98         torture_comment(tctx, "Testing maximum number of open files\n");
99
100         for (i = 0; i < max_handles; i++) {
101                 char *name;
102                 struct smb2_create create = { };
103
104                 name = talloc_asprintf(tctx, "%s\\%zu\\%zu", dname, i / 1000, i);
105                 torture_assert_goto(tctx, (name != NULL), ret, done,
106                                     "no memory for file name\n");
107
108                 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
109                 create.in.create_options = 0;
110                 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
111                 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
112                         NTCREATEX_SHARE_ACCESS_WRITE |
113                         NTCREATEX_SHARE_ACCESS_DELETE;
114                 create.in.create_disposition = NTCREATEX_DISP_CREATE;
115                 create.in.fname = name;
116
117                 status = smb2_create(tree, tctx, &create);
118                 if (!NT_STATUS_IS_OK(status)) {
119                         torture_comment(tctx, "create of %s failed: %s\n",
120                                         name, nt_errstr(status));
121                         talloc_free(name);
122                         break;
123                 }
124                 talloc_free(name);
125
126                 handles[i] = create.out.file.handle;
127         }
128
129         maxfid = i;
130         if (maxfid == max_handles) {
131                 torture_comment(tctx, "Reached test limit of %zu open files. "
132                                 "Adjust to higher test with "
133                                 "--option=torture:maxopenfiles=NNN\n", maxfid);
134         }
135
136         torture_comment(tctx, "Cleanup open files\n");
137
138         for (i = 0; i < maxfid; i++) {
139                 union smb_setfileinfo sfinfo = { };
140
141                 sfinfo.disposition_info.in.delete_on_close = 1;
142                 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
143                 sfinfo.generic.in.file.handle = handles[i];
144
145                 status = smb2_setinfo_file(tree, &sfinfo);
146                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
147                                                 "SETINFO failed\n");
148
149                 status = smb2_util_close(tree, handles[i]);
150                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
151                                                 "CLOSE failed\n");
152         }
153
154 done:
155         smb2_deltree(tree, dname);
156         talloc_free(handles);
157
158         return ret;
159 }