s3:smbd: s/event_add_fd/tevent_add_fd and s/EVENT_FD_/TEVENT_FD_
[Samba/gebeck_regimport.git] / source4 / torture / nbench / nbench.c
blob3258e1915d5827532db00ce94e46dee7f663b653
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"
27 #include "torture/nbench/proto.h"
29 int nbench_line_count = 0;
30 static int timelimit = 600;
31 static int warmup;
32 static const char *loadfile;
33 static int read_only;
35 #define ival(s) strtoll(s, NULL, 0)
37 static unsigned long nb_max_retries;
39 #define NB_RETRY(op) \
40 for (n=0;n<=nb_max_retries && !op;n++) do_reconnect(&cli, tctx, client)
42 static void do_reconnect(struct smbcli_state **cli, struct torture_context *tctx, int client)
44 int n;
45 printf("[%d] Reconnecting client %d\n", nbench_line_count, client);
46 for (n=0;n<nb_max_retries;n++) {
47 if (nb_reconnect(cli, tctx, client)) {
48 printf("[%d] Reconnected client %d\n", nbench_line_count, client);
49 return;
52 printf("[%d] Failed to reconnect client %d\n", nbench_line_count, client);
53 nb_exit(1);
56 /* run a test that simulates an approximate netbench client load */
57 static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
59 int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
60 int i;
61 char line[1024];
62 char *cname;
63 FILE *f;
64 bool correct = true;
65 double target_rate = torture_setting_double(tctx, "targetrate", 0);
66 int n = 0;
68 if (target_rate != 0 && client == 0) {
69 printf("Targeting %.4f MByte/sec\n", target_rate);
72 nb_setup(cli, client);
74 if (torture_nprocs == 1) {
75 if (!read_only) {
76 NB_RETRY(torture_setup_dir(cli, "\\clients"));
80 asprintf(&cname, "client%d", client+1);
82 f = fopen(loadfile, "r");
84 if (!f) {
85 perror(loadfile);
86 return false;
89 again:
90 nbio_time_reset();
92 while (fgets(line, sizeof(line)-1, f)) {
93 NTSTATUS status;
94 const char **params0, **params;
96 nbench_line_count++;
98 if ((strlen(line) > 0) && line[strlen(line)-1] == '\n') {
99 line[strlen(line)-1] = 0;
102 all_string_sub(line, "client1", cname, sizeof(line));
104 params = params0 = const_str_list(
105 str_list_make_shell(NULL, line, " "));
106 i = str_list_length(params);
108 if (i > 0 && isdigit(params[0][0])) {
109 double targett = strtod(params[0], NULL);
110 if (target_rate != 0) {
111 nbio_target_rate(target_rate);
112 } else {
113 nbio_time_delay(targett);
115 params++;
116 i--;
117 } else if (target_rate != 0) {
118 nbio_target_rate(target_rate);
121 if (i < 2 || params[0][0] == '#') continue;
123 if (!strncmp(params[0],"SMB", 3)) {
124 printf("ERROR: You are using a dbench 1 load file\n");
125 nb_exit(1);
128 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
129 strncmp(params[i-1], "0x", 2) != 0) {
130 printf("Badly formed status at line %d\n", nbench_line_count);
131 talloc_free(params);
132 continue;
135 /* accept numeric or string status codes */
136 if (strncmp(params[i-1], "0x", 2) == 0) {
137 status = NT_STATUS(strtoul(params[i-1], NULL, 16));
138 } else {
139 status = nt_status_string_to_code(params[i-1]);
142 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
144 if (!strcmp(params[0],"NTCreateX")) {
145 NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]),
146 ival(params[4]), status));
147 } else if (!strcmp(params[0],"Close")) {
148 NB_RETRY(nb_close(ival(params[1]), status));
149 } else if (!read_only && !strcmp(params[0],"Rename")) {
150 NB_RETRY(nb_rename(params[1], params[2], status, n>0));
151 } else if (!read_only && !strcmp(params[0],"Unlink")) {
152 NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
153 } else if (!read_only && !strcmp(params[0],"Deltree")) {
154 NB_RETRY(nb_deltree(params[1], n>0));
155 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
156 NB_RETRY(nb_rmdir(params[1], status, n>0));
157 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
158 NB_RETRY(nb_mkdir(params[1], status, n>0));
159 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
160 NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
161 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
162 NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
163 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
164 NB_RETRY(nb_qfsinfo(ival(params[1]), status));
165 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
166 NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
167 } else if (!strcmp(params[0],"FIND_FIRST")) {
168 NB_RETRY(nb_findfirst(params[1], ival(params[2]),
169 ival(params[3]), ival(params[4]), status));
170 } else if (!read_only && !strcmp(params[0],"WriteX")) {
171 NB_RETRY(nb_writex(ival(params[1]),
172 ival(params[2]), ival(params[3]), ival(params[4]),
173 status));
174 } else if (!read_only && !strcmp(params[0],"Write")) {
175 NB_RETRY(nb_write(ival(params[1]),
176 ival(params[2]), ival(params[3]), ival(params[4]),
177 status));
178 } else if (!strcmp(params[0],"LockX")) {
179 NB_RETRY(nb_lockx(ival(params[1]),
180 ival(params[2]), ival(params[3]), status));
181 } else if (!strcmp(params[0],"UnlockX")) {
182 NB_RETRY(nb_unlockx(ival(params[1]),
183 ival(params[2]), ival(params[3]), status));
184 } else if (!strcmp(params[0],"ReadX")) {
185 NB_RETRY(nb_readx(ival(params[1]),
186 ival(params[2]), ival(params[3]), ival(params[4]),
187 status));
188 } else if (!strcmp(params[0],"Flush")) {
189 NB_RETRY(nb_flush(ival(params[1]), status));
190 } else if (!strcmp(params[0],"Sleep")) {
191 nb_sleep(ival(params[1]), status);
192 } else {
193 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
196 if (n > nb_max_retries) {
197 printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
198 nb_exit(1);
201 talloc_free(params0);
203 if (nb_tick()) goto done;
206 rewind(f);
207 goto again;
209 done:
210 fclose(f);
212 if (!read_only && torture_nprocs == 1) {
213 smbcli_deltree(cli->tree, "\\clients");
215 if (!torture_close_connection(cli)) {
216 correct = false;
219 return correct;
223 /* run a test that simulates an approximate netbench client load */
224 bool torture_nbench(struct torture_context *torture)
226 bool correct = true;
227 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
228 struct smbcli_state *cli;
229 const char *p;
231 read_only = torture_setting_bool(torture, "readonly", false);
233 nb_max_retries = torture_setting_int(torture, "nretries", 1);
235 p = torture_setting_string(torture, "timelimit", NULL);
236 if (p && *p) {
237 timelimit = atoi(p);
240 warmup = timelimit / 20;
242 loadfile = torture_setting_string(torture, "loadfile", NULL);
243 if (!loadfile || !*loadfile) {
244 loadfile = "client.txt";
247 if (torture_nprocs > 1) {
248 if (!torture_open_connection(&cli, torture, 0)) {
249 return false;
252 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
253 return false;
257 nbio_shmem(torture_nprocs, timelimit, warmup);
259 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
260 timelimit, loadfile, warmup);
262 /* we need to reset SIGCHLD here as the name resolution
263 library may have changed it. We rely on correct signals
264 from childs in the main torture code which reaps
265 children. This is why smbtorture BENCH-NBENCH was sometimes
266 failing */
267 signal(SIGCHLD, SIG_DFL);
270 signal(SIGALRM, nb_alarm);
271 alarm(1);
272 torture_create_procs(torture, run_netbench, &correct);
273 alarm(0);
275 if (!read_only && torture_nprocs > 1) {
276 smbcli_deltree(cli->tree, "\\clients");
279 printf("\nThroughput %g MB/sec\n", nbio_result());
280 return correct;
283 NTSTATUS torture_nbench_init(void)
285 struct torture_suite *suite = torture_suite_create(
286 talloc_autofree_context(), "bench");
288 torture_suite_add_simple_test(suite, "nbench", torture_nbench);
290 suite->description = talloc_strdup(suite, "Benchmarks");
292 torture_register_suite(suite);
293 return NT_STATUS_OK;