r7431: this should fix the bug that mkaplan and I noticed which is that
[sfrench/samba-autobuild/.git] / source4 / torture / nbench / nbench.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester - NBENCH test
4    Copyright (C) Andrew Tridgell 1997-2004
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "system/filesys.h"
23 #include "pstring.h"
24
25 int nbench_line_count = 0;
26 static int timelimit = 600;
27 static int warmup;
28 static const char *loadfile;
29
30 #define ival(s) strtol(s, NULL, 0)
31
32 /* run a test that simulates an approximate netbench client load */
33 static BOOL run_netbench(struct smbcli_state *cli, int client)
34 {
35         extern int torture_nprocs;
36         int i;
37         pstring line;
38         char *cname;
39         FILE *f;
40         fstring params[20];
41         const char *p;
42         BOOL correct = True;
43
44         if (torture_nprocs == 1) {
45                 if (!torture_setup_dir(cli, "\\clients")) {
46                         return False;
47                 }
48         }
49
50         nb_setup(cli, client);
51
52         asprintf(&cname, "client%d", client+1);
53
54         f = fopen(loadfile, "r");
55
56         if (!f) {
57                 perror(loadfile);
58                 return False;
59         }
60
61 again:
62         while (fgets(line, sizeof(line)-1, f)) {
63                 NTSTATUS status;
64
65                 nbench_line_count++;
66
67                 line[strlen(line)-1] = 0;
68
69                 all_string_sub(line,"client1", cname, sizeof(line));
70                 
71                 p = line;
72                 for (i=0; 
73                      i<19 && next_token(&p, params[i], " ", sizeof(fstring));
74                      i++) ;
75
76                 params[i][0] = 0;
77
78                 if (i < 2 || params[0][0] == '#') continue;
79
80                 if (!strncmp(params[0],"SMB", 3)) {
81                         printf("ERROR: You are using a dbench 1 load file\n");
82                         exit(1);
83                 }
84
85                 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
86                         printf("Badly formed status at line %d\n", nbench_line_count);
87                         continue;
88                 }
89
90                 status = nt_status_string_to_code(params[i-1]);
91
92                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
93
94                 if (!strcmp(params[0],"NTCreateX")) {
95                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
96                                    ival(params[4]), status);
97                 } else if (!strcmp(params[0],"Close")) {
98                         nb_close(ival(params[1]), status);
99                 } else if (!strcmp(params[0],"Rename")) {
100                         nb_rename(params[1], params[2], status);
101                 } else if (!strcmp(params[0],"Unlink")) {
102                         nb_unlink(params[1], ival(params[2]), status);
103                 } else if (!strcmp(params[0],"Deltree")) {
104                         nb_deltree(params[1]);
105                 } else if (!strcmp(params[0],"Rmdir")) {
106                         nb_rmdir(params[1], status);
107                 } else if (!strcmp(params[0],"Mkdir")) {
108                         nb_mkdir(params[1], status);
109                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
110                         nb_qpathinfo(params[1], ival(params[2]), status);
111                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
112                         nb_qfileinfo(ival(params[1]), ival(params[2]), status);
113                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
114                         nb_qfsinfo(ival(params[1]), status);
115                 } else if (!strcmp(params[0],"SET_FILE_INFORMATION")) {
116                         nb_sfileinfo(ival(params[1]), ival(params[2]), status);
117                 } else if (!strcmp(params[0],"FIND_FIRST")) {
118                         nb_findfirst(params[1], ival(params[2]), 
119                                      ival(params[3]), ival(params[4]), status);
120                 } else if (!strcmp(params[0],"WriteX")) {
121                         nb_writex(ival(params[1]), 
122                                   ival(params[2]), ival(params[3]), ival(params[4]),
123                                   status);
124                 } else if (!strcmp(params[0],"Write")) {
125                         nb_write(ival(params[1]), 
126                                  ival(params[2]), ival(params[3]), ival(params[4]),
127                                  status);
128                 } else if (!strcmp(params[0],"LockX")) {
129                         nb_lockx(ival(params[1]), 
130                                  ival(params[2]), ival(params[3]), status);
131                 } else if (!strcmp(params[0],"UnlockX")) {
132                         nb_unlockx(ival(params[1]), 
133                                  ival(params[2]), ival(params[3]), status);
134                 } else if (!strcmp(params[0],"ReadX")) {
135                         nb_readx(ival(params[1]), 
136                                  ival(params[2]), ival(params[3]), ival(params[4]),
137                                  status);
138                 } else if (!strcmp(params[0],"Flush")) {
139                         nb_flush(ival(params[1]), status);
140                 } else if (!strcmp(params[0],"Sleep")) {
141                         nb_sleep(ival(params[1]), status);
142                 } else {
143                         printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
144                 }
145                 
146                 if (nb_tick()) goto done;
147         }
148
149         rewind(f);
150         goto again;
151
152 done:
153         fclose(f);
154
155         if (torture_nprocs == 1) {
156                 smbcli_deltree(cli->tree, "\\clients");
157         }
158         if (!torture_close_connection(cli)) {
159                 correct = False;
160         }
161         
162         return correct;
163 }
164
165
166 /* run a test that simulates an approximate netbench client load */
167 BOOL torture_nbench(void)
168 {
169         BOOL correct = True;
170         extern int torture_nprocs;
171         struct smbcli_state *cli;
172         const char *p;
173
174         p = lp_parm_string(-1, "torture", "timelimit");
175         if (p && *p) {
176                 timelimit = atoi(p);
177         }
178
179         warmup = timelimit / 20;
180
181         loadfile =  lp_parm_string(-1, "torture", "loadfile");
182         if (!loadfile || !*loadfile) {
183                 loadfile = "client.txt";
184         }
185
186         if (torture_nprocs > 1) {
187                 if (!torture_open_connection(&cli)) {
188                         return False;
189                 }
190
191                 if (!torture_setup_dir(cli, "\\clients")) {
192                         return False;
193                 }
194         }
195
196         nbio_shmem(torture_nprocs, timelimit, warmup);
197
198         printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
199                timelimit, loadfile, warmup);
200
201         /* we need to reset SIGCHLD here as the name resolution
202            library may have changed it. We rely on correct signals
203            from childs in the main torture code which reaps
204            children. This is why smbtorture BENCH-NBENCH was sometimes
205            failing */
206         signal(SIGCHLD, SIG_DFL);
207
208
209         signal(SIGALRM, nb_alarm);
210         alarm(1);
211         torture_create_procs(run_netbench, &correct);
212         alarm(0);
213
214         if (torture_nprocs > 1) {
215                 smbcli_deltree(cli->tree, "\\clients");
216         }
217
218         printf("\nThroughput %g MB/sec\n", nbio_result());
219         return correct;
220 }