s3: smbd: Now we have shown dst_dirfsp is always NULL, remove the parameter from...
[Samba.git] / source4 / torture / nbench / nbench.c
blob05ff3aba21b6804603c1e56ae3c6888db02db28d
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester - NBENCH test
4 Copyright (C) Andrew Tridgell 1997-2004
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 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "libcli/libcli.h"
22 #include "torture/util.h"
23 #include "torture/smbtorture.h"
24 #include "system/filesys.h"
25 #include "system/locale.h"
26 #include "lib/util/smb_strtox.h"
28 #include "torture/nbench/proto.h"
30 int nbench_line_count = 0;
31 static int timelimit = 600;
32 static int warmup;
33 static const char *loadfile;
34 static int read_only;
36 #define ival(s) strtoll(s, NULL, 0)
38 static unsigned long nb_max_retries;
40 #define NB_RETRY(op) \
41 for (n=0;n<=nb_max_retries && !op;n++) do_reconnect(&cli, tctx, client)
43 static void do_reconnect(struct smbcli_state **cli, struct torture_context *tctx, int client)
45 int n;
46 printf("[%d] Reconnecting client %d\n", nbench_line_count, client);
47 for (n=0;n<nb_max_retries;n++) {
48 if (nb_reconnect(cli, tctx, client)) {
49 printf("[%d] Reconnected client %d\n", nbench_line_count, client);
50 return;
53 printf("[%d] Failed to reconnect client %d\n", nbench_line_count, client);
54 nb_exit(1);
57 /* run a test that simulates an approximate netbench client load */
58 static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
60 int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
61 int i;
62 char line[1024];
63 char *cname;
64 FILE *f;
65 bool correct = true;
66 double target_rate = torture_setting_double(tctx, "targetrate", 0);
67 int n = 0;
68 int ret;
70 if (target_rate != 0 && client == 0) {
71 printf("Targeting %.4f MByte/sec\n", target_rate);
74 nb_setup(cli, client);
76 if (torture_nprocs == 1) {
77 if (!read_only) {
78 NB_RETRY(torture_setup_dir(cli, "\\clients"));
82 ret = asprintf(&cname, "client%d", client+1);
83 if (ret == -1) {
84 return false;
87 f = fopen(loadfile, "r");
89 if (!f) {
90 perror(loadfile);
91 return false;
94 again:
95 nbio_time_reset();
97 while (fgets(line, sizeof(line)-1, f)) {
98 NTSTATUS status;
99 const char **params0, **params;
100 unsigned long int tmp;
101 int error = 0;
103 nbench_line_count++;
105 if ((strlen(line) > 0) && line[strlen(line)-1] == '\n') {
106 line[strlen(line)-1] = 0;
109 all_string_sub(line, "client1", cname, sizeof(line));
111 params = params0 = const_str_list(
112 str_list_make_shell(NULL, line, " "));
113 i = str_list_length(params);
115 if (i > 0 && isdigit(params[0][0])) {
116 double targett = strtod(params[0], NULL);
117 if (target_rate != 0) {
118 nbio_target_rate(target_rate);
119 } else {
120 nbio_time_delay(targett);
122 params++;
123 i--;
124 } else if (target_rate != 0) {
125 nbio_target_rate(target_rate);
128 if (i < 2 || params[0][0] == '#') continue;
130 if (!strncmp(params[0],"SMB", 3)) {
131 printf("ERROR: You are using a dbench 1 load file\n");
132 nb_exit(1);
135 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
136 strncmp(params[i-1], "0x", 2) != 0) {
137 printf("Badly formed status at line %d\n", nbench_line_count);
138 talloc_free(params);
139 continue;
142 /* accept numeric or string status codes */
143 if (strncmp(params[i-1], "0x", 2) == 0) {
144 tmp = smb_strtoul(params[i-1],
145 NULL,
147 &error,
148 SMB_STR_STANDARD);
149 if (error != 0) {
150 tmp = error;
152 status = NT_STATUS(tmp);
153 } else {
154 status = nt_status_string_to_code(params[i-1]);
157 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
159 if (!strcmp(params[0],"NTCreateX")) {
160 NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]),
161 ival(params[4]), status));
162 } else if (!strcmp(params[0],"Close")) {
163 NB_RETRY(nb_close(ival(params[1]), status));
164 } else if (!read_only && !strcmp(params[0],"Rename")) {
165 NB_RETRY(nb_rename(params[1], params[2], status, n>0));
166 } else if (!read_only && !strcmp(params[0],"Unlink")) {
167 NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
168 } else if (!read_only && !strcmp(params[0],"Deltree")) {
169 NB_RETRY(nb_deltree(params[1], n>0));
170 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
171 NB_RETRY(nb_rmdir(params[1], status, n>0));
172 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
173 NB_RETRY(nb_mkdir(params[1], status, n>0));
174 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
175 NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
176 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
177 NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
178 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
179 NB_RETRY(nb_qfsinfo(ival(params[1]), status));
180 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
181 NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
182 } else if (!strcmp(params[0],"FIND_FIRST")) {
183 NB_RETRY(nb_findfirst(params[1], ival(params[2]),
184 ival(params[3]), ival(params[4]), status));
185 } else if (!read_only && !strcmp(params[0],"WriteX")) {
186 NB_RETRY(nb_writex(ival(params[1]),
187 ival(params[2]), ival(params[3]), ival(params[4]),
188 status));
189 } else if (!read_only && !strcmp(params[0],"Write")) {
190 NB_RETRY(nb_write(ival(params[1]),
191 ival(params[2]), ival(params[3]), ival(params[4]),
192 status));
193 } else if (!strcmp(params[0],"LockX")) {
194 NB_RETRY(nb_lockx(ival(params[1]),
195 ival(params[2]), ival(params[3]), status));
196 } else if (!strcmp(params[0],"UnlockX")) {
197 NB_RETRY(nb_unlockx(ival(params[1]),
198 ival(params[2]), ival(params[3]), status));
199 } else if (!strcmp(params[0],"ReadX")) {
200 NB_RETRY(nb_readx(ival(params[1]),
201 ival(params[2]), ival(params[3]), ival(params[4]),
202 status));
203 } else if (!strcmp(params[0],"Flush")) {
204 NB_RETRY(nb_flush(ival(params[1]), status));
205 } else if (!strcmp(params[0],"Sleep")) {
206 nb_sleep(ival(params[1]), status);
207 } else {
208 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
211 if (n > nb_max_retries) {
212 printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
213 nb_exit(1);
216 talloc_free(params0);
218 if (nb_tick()) goto done;
221 rewind(f);
222 goto again;
224 done:
225 fclose(f);
227 if (!read_only && torture_nprocs == 1) {
228 smbcli_deltree(cli->tree, "\\clients");
230 if (!torture_close_connection(cli)) {
231 correct = false;
234 return correct;
238 /* run a test that simulates an approximate netbench client load */
239 bool torture_nbench(struct torture_context *torture)
241 bool correct = true;
242 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
243 struct smbcli_state *cli;
244 const char *p;
246 read_only = torture_setting_bool(torture, "readonly", false);
248 nb_max_retries = torture_setting_int(torture, "nretries", 1);
250 p = torture_setting_string(torture, "timelimit", NULL);
251 if (p && *p) {
252 timelimit = atoi(p);
255 warmup = timelimit / 20;
257 loadfile = torture_setting_string(torture, "loadfile", NULL);
258 if (!loadfile || !*loadfile) {
259 loadfile = "client.txt";
262 if (torture_nprocs > 1) {
263 if (!torture_open_connection(&cli, torture, 0)) {
264 return false;
267 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
268 return false;
272 nbio_shmem(torture_nprocs, timelimit, warmup);
274 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
275 timelimit, loadfile, warmup);
277 /* we need to reset SIGCHLD here as the name resolution
278 library may have changed it. We rely on correct signals
279 from children in the main torture code which reaps
280 children. This is why smbtorture BENCH-NBENCH was sometimes
281 failing */
282 signal(SIGCHLD, SIG_DFL);
285 signal(SIGALRM, nb_alarm);
286 alarm(1);
287 torture_create_procs(torture, run_netbench, &correct);
288 alarm(0);
290 if (!read_only && torture_nprocs > 1) {
291 smbcli_deltree(cli->tree, "\\clients");
294 printf("\nThroughput %g MB/sec\n", nbio_result());
295 return correct;
298 NTSTATUS torture_nbench_init(TALLOC_CTX *ctx)
300 struct torture_suite *suite = torture_suite_create(
301 ctx, "bench");
303 torture_suite_add_simple_test(suite, "nbench", torture_nbench);
305 suite->description = talloc_strdup(suite, "Benchmarks");
307 torture_register_suite(ctx, suite);
308 return NT_STATUS_OK;