Get medieval on our ass about SMB1 file descriptors being 16 bits, not an int.
[nivanova/samba-autobuild/.git] / source3 / torture / nbio.c
1 #define NBDEBUG 0
2
3 /* 
4    Unix SMB/CIFS implementation.
5    SMB torture tester
6    Copyright (C) Andrew Tridgell 1997-1998
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
24 #define MAX_FILES 1000
25
26 static char buf[70000];
27 extern int line_count;
28 extern int nbio_id;
29 static int nprocs;
30
31 static struct {
32         int fd;
33         int handle;
34 } ftable[MAX_FILES];
35
36 static struct children {
37         double bytes_in, bytes_out;
38         int line;
39         int done;
40 } *children;
41
42 double nbio_total(void)
43 {
44         int i;
45         double total = 0;
46         for (i=0;i<nprocs;i++) {
47                 total += children[i].bytes_out + children[i].bytes_in;
48         }
49         return total;
50 }
51
52 void nb_alarm(int ignore)
53 {
54         int i;
55         int lines=0, num_clients=0;
56         if (nbio_id != -1) return;
57
58         for (i=0;i<nprocs;i++) {
59                 lines += children[i].line;
60                 if (!children[i].done) num_clients++;
61         }
62
63         printf("%4d  %8d  %.2f MB/sec\r", num_clients, lines/nprocs, 1.0e-6 * nbio_total() / end_timer());
64
65         signal(SIGALRM, nb_alarm);
66         alarm(1);       
67 }
68
69 void nbio_shmem(int n)
70 {
71         nprocs = n;
72         children = (struct children *)shm_setup(sizeof(*children) * nprocs);
73         if (!children) {
74                 printf("Failed to setup shared memory!\n");
75                 exit(1);
76         }
77 }
78
79 #if 0
80 static int ne_find_handle(int handle)
81 {
82         int i;
83         children[nbio_id].line = line_count;
84         for (i=0;i<MAX_FILES;i++) {
85                 if (ftable[i].handle == handle) return i;
86         }
87         return -1;
88 }
89 #endif
90
91 static int find_handle(int handle)
92 {
93         int i;
94         children[nbio_id].line = line_count;
95         for (i=0;i<MAX_FILES;i++) {
96                 if (ftable[i].handle == handle) return i;
97         }
98         printf("(%d) ERROR: handle %d was not found\n", 
99                line_count, handle);
100         exit(1);
101
102         return -1;              /* Not reached */
103 }
104
105
106 static struct cli_state *c;
107
108 static void sigsegv(int sig)
109 {
110         char line[200];
111         printf("segv at line %d\n", line_count);
112         slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d", 
113                 (int)getpid(), (int)getpid());
114         if (system(line) == -1) {
115                 printf("system() failed\n");
116         }
117         exit(1);
118 }
119
120 void nb_setup(struct cli_state *cli)
121 {
122         signal(SIGSEGV, sigsegv);
123         c = cli;
124         start_timer();
125         children[nbio_id].done = 0;
126 }
127
128
129 void nb_unlink(const char *fname)
130 {
131         if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
132 #if NBDEBUG
133                 printf("(%d) unlink %s failed (%s)\n", 
134                        line_count, fname, cli_errstr(c));
135 #endif
136         }
137 }
138
139
140 void nb_createx(const char *fname, 
141                 unsigned create_options, unsigned create_disposition, int handle)
142 {
143         uint16_t fd = (uint16_t)-1;
144         int i;
145         NTSTATUS status;
146         uint32 desired_access;
147
148         if (create_options & FILE_DIRECTORY_FILE) {
149                 desired_access = FILE_READ_DATA;
150         } else {
151                 desired_access = FILE_READ_DATA | FILE_WRITE_DATA;
152         }
153
154         status = cli_ntcreate(c, fname, 0, 
155                                 desired_access,
156                                 0x0,
157                                 FILE_SHARE_READ|FILE_SHARE_WRITE, 
158                                 create_disposition, 
159                                 create_options, 0, &fd);
160         if (!NT_STATUS_IS_OK(status) && handle != -1) {
161                 printf("ERROR: cli_ntcreate failed for %s - %s\n",
162                        fname, cli_errstr(c));
163                 exit(1);
164         }
165         if (NT_STATUS_IS_OK(status) && handle == -1) {
166                 printf("ERROR: cli_ntcreate succeeded for %s\n", fname);
167                 exit(1);
168         }
169         if (fd == (uint16_t)-1) return;
170
171         for (i=0;i<MAX_FILES;i++) {
172                 if (ftable[i].handle == 0) break;
173         }
174         if (i == MAX_FILES) {
175                 printf("(%d) file table full for %s\n", line_count, 
176                        fname);
177                 exit(1);
178         }
179         ftable[i].handle = handle;
180         ftable[i].fd = fd;
181 }
182
183 void nb_writex(int handle, int offset, int size, int ret_size)
184 {
185         int i;
186
187         if (buf[0] == 0) memset(buf, 1, sizeof(buf));
188
189         i = find_handle(handle);
190         if (cli_write(c, ftable[i].fd, 0, buf, offset, size) != ret_size) {
191                 printf("(%d) ERROR: write failed on handle %d, fd %d \
192 errno %d (%s)\n", line_count, handle, ftable[i].fd, errno, strerror(errno));
193                 exit(1);
194         }
195
196         children[nbio_id].bytes_out += ret_size;
197 }
198
199 void nb_readx(int handle, int offset, int size, int ret_size)
200 {
201         int i, ret;
202
203         i = find_handle(handle);
204         if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != ret_size) {
205                 printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s)\n",
206                         line_count, handle, offset, size, ret, ftable[i].fd, errno, strerror(errno));
207                 exit(1);
208         }
209         children[nbio_id].bytes_in += ret_size;
210 }
211
212 void nb_close(int handle)
213 {
214         int i;
215         i = find_handle(handle);
216         if (!cli_close(c, ftable[i].fd)) {
217                 printf("(%d) close failed on handle %d\n", line_count, handle);
218                 exit(1);
219         }
220         ftable[i].handle = 0;
221 }
222
223 void nb_rmdir(const char *fname)
224 {
225         if (!NT_STATUS_IS_OK(cli_rmdir(c, fname))) {
226                 printf("ERROR: rmdir %s failed (%s)\n", 
227                        fname, cli_errstr(c));
228                 exit(1);
229         }
230 }
231
232 void nb_rename(const char *oldname, const char *newname)
233 {
234         if (!NT_STATUS_IS_OK(cli_rename(c, oldname, newname))) {
235                 printf("ERROR: rename %s %s failed (%s)\n", 
236                        oldname, newname, cli_errstr(c));
237                 exit(1);
238         }
239 }
240
241
242 void nb_qpathinfo(const char *fname)
243 {
244         cli_qpathinfo(c, fname, NULL, NULL, NULL, NULL, NULL);
245 }
246
247 void nb_qfileinfo(int fnum)
248 {
249         int i;
250         i = find_handle(fnum);
251         cli_qfileinfo(c, ftable[i].fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
252 }
253
254 void nb_qfsinfo(int level)
255 {
256         int bsize, total, avail;
257         /* this is not the right call - we need cli_qfsinfo() */
258         cli_dskattr(c, &bsize, &total, &avail);
259 }
260
261 static void find_fn(const char *mnt, file_info *finfo, const char *name, void *state)
262 {
263         /* noop */
264 }
265
266 void nb_findfirst(const char *mask)
267 {
268         cli_list(c, mask, 0, find_fn, NULL);
269 }
270
271 void nb_flush(int fnum)
272 {
273         int i;
274         i = find_handle(fnum);
275         /* hmmm, we don't have cli_flush() yet */
276 }
277
278 static int total_deleted;
279
280 static void delete_fn(const char *mnt, file_info *finfo, const char *name, void *state)
281 {
282         char *s, *n;
283         if (finfo->name[0] == '.') return;
284
285         n = SMB_STRDUP(name);
286         n[strlen(n)-1] = 0;
287         if (asprintf(&s, "%s%s", n, finfo->name) == -1) {
288                 printf("asprintf failed\n");
289                 return;
290         }
291         if (finfo->mode & aDIR) {
292                 char *s2;
293                 if (asprintf(&s2, "%s\\*", s) == -1) {
294                         printf("asprintf failed\n");
295                         return;
296                 }
297                 cli_list(c, s2, aDIR, delete_fn, NULL);
298                 nb_rmdir(s);
299         } else {
300                 total_deleted++;
301                 nb_unlink(s);
302         }
303         free(s);
304         free(n);
305 }
306
307 void nb_deltree(const char *dname)
308 {
309         char *mask;
310         if (asprintf(&mask, "%s\\*", dname) == -1) {
311                 printf("asprintf failed\n");
312                 return;
313         }
314
315         total_deleted = 0;
316         cli_list(c, mask, aDIR, delete_fn, NULL);
317         free(mask);
318         cli_rmdir(c, dname);
319
320         if (total_deleted) printf("WARNING: Cleaned up %d files\n", total_deleted);
321 }
322
323
324 void nb_cleanup(void)
325 {
326         cli_rmdir(c, "clients");
327         children[nbio_id].done = 1;
328 }