dbe3fac9d397a84794ef575473854555f2182b1a
[sfrench/samba-autobuild/.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         max_handles = torture_setting_int(tctx, "maxopenfiles", 0x11000);
40
41         if (!torture_smb2_connection(tctx, &tree)) {
42                 return false;
43         }
44
45         handles = talloc_array(tctx, struct smb2_handle, max_handles);
46         if (handles == 0) {
47                 torture_fail(tctx, "Could not allocate handles array.\n");
48                 return false;
49         }
50
51         smb2_deltree(tree, dname);
52
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);
57
58         torture_comment(tctx, "Creating subdirectories\n");
59
60         for (i = 0; i < max_handles; i += 1000) {
61                 char *name;
62                 struct smb2_create create = { };
63                 struct smb2_close close = { };
64
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");
68
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;
77
78                 status = smb2_create(tree, tctx, &create);
79                 talloc_free(name);
80
81                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
82                                                 "CREATE directory failed\n");
83
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");
88         }
89
90         torture_comment(tctx, "Testing maximum number of open files\n");
91
92         for (i = 0; i < max_handles; i++) {
93                 char *name;
94                 struct smb2_create create = { };
95
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");
99
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;
108
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));
113                         talloc_free(name);
114                         break;
115                 }
116                 talloc_free(name);
117
118                 handles[i] = create.out.file.handle;
119         }
120
121         maxfid = i;
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);
126         }
127
128         torture_comment(tctx, "Cleanup open files\n");
129
130         for (i = 0; i < maxfid; i++) {
131                 union smb_setfileinfo sfinfo = { };
132
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];
136
137                 status = smb2_setinfo_file(tree, &sfinfo);
138                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
139                                                 "SETINFO failed\n");
140
141                 status = smb2_util_close(tree, handles[i]);
142                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
143                                                 "CLOSE failed\n");
144         }
145
146 done:
147         smb2_deltree(tree, dname);
148         talloc_free(handles);
149
150         return ret;
151 }