Add an entry for the "check" command to the tdbtool manpage.
[Samba/gebeck_regimport.git] / source4 / torture / nbench / nbench.c
blob5a4037f906d1d73dba685ae5b9922ca0ab2100de
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;
68 if (target_rate != 0 && client == 0) {
69 printf("Targetting %.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 line[strlen(line)-1] = 0;
100 all_string_sub(line,"client1", cname, sizeof(line));
102 params = params0 = str_list_make_shell(NULL, line, " ");
103 i = str_list_length(params);
105 if (i > 0 && isdigit(params[0][0])) {
106 double targett = strtod(params[0], NULL);
107 if (target_rate != 0) {
108 nbio_target_rate(target_rate);
109 } else {
110 nbio_time_delay(targett);
112 params++;
113 i--;
114 } else if (target_rate != 0) {
115 nbio_target_rate(target_rate);
118 if (i < 2 || params[0][0] == '#') continue;
120 if (!strncmp(params[0],"SMB", 3)) {
121 printf("ERROR: You are using a dbench 1 load file\n");
122 nb_exit(1);
125 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
126 strncmp(params[i-1], "0x", 2) != 0) {
127 printf("Badly formed status at line %d\n", nbench_line_count);
128 talloc_free(params);
129 continue;
132 /* accept numeric or string status codes */
133 if (strncmp(params[i-1], "0x", 2) == 0) {
134 status = NT_STATUS(strtoul(params[i-1], NULL, 16));
135 } else {
136 status = nt_status_string_to_code(params[i-1]);
139 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
141 if (!strcmp(params[0],"NTCreateX")) {
142 NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]),
143 ival(params[4]), status));
144 } else if (!strcmp(params[0],"Close")) {
145 NB_RETRY(nb_close(ival(params[1]), status));
146 } else if (!read_only && !strcmp(params[0],"Rename")) {
147 NB_RETRY(nb_rename(params[1], params[2], status, n>0));
148 } else if (!read_only && !strcmp(params[0],"Unlink")) {
149 NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
150 } else if (!read_only && !strcmp(params[0],"Deltree")) {
151 NB_RETRY(nb_deltree(params[1], n>0));
152 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
153 NB_RETRY(nb_rmdir(params[1], status, n>0));
154 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
155 NB_RETRY(nb_mkdir(params[1], status, n>0));
156 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
157 NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
158 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
159 NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
160 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
161 NB_RETRY(nb_qfsinfo(ival(params[1]), status));
162 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
163 NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
164 } else if (!strcmp(params[0],"FIND_FIRST")) {
165 NB_RETRY(nb_findfirst(params[1], ival(params[2]),
166 ival(params[3]), ival(params[4]), status));
167 } else if (!read_only && !strcmp(params[0],"WriteX")) {
168 NB_RETRY(nb_writex(ival(params[1]),
169 ival(params[2]), ival(params[3]), ival(params[4]),
170 status));
171 } else if (!read_only && !strcmp(params[0],"Write")) {
172 NB_RETRY(nb_write(ival(params[1]),
173 ival(params[2]), ival(params[3]), ival(params[4]),
174 status));
175 } else if (!strcmp(params[0],"LockX")) {
176 NB_RETRY(nb_lockx(ival(params[1]),
177 ival(params[2]), ival(params[3]), status));
178 } else if (!strcmp(params[0],"UnlockX")) {
179 NB_RETRY(nb_unlockx(ival(params[1]),
180 ival(params[2]), ival(params[3]), status));
181 } else if (!strcmp(params[0],"ReadX")) {
182 NB_RETRY(nb_readx(ival(params[1]),
183 ival(params[2]), ival(params[3]), ival(params[4]),
184 status));
185 } else if (!strcmp(params[0],"Flush")) {
186 NB_RETRY(nb_flush(ival(params[1]), status));
187 } else if (!strcmp(params[0],"Sleep")) {
188 nb_sleep(ival(params[1]), status);
189 } else {
190 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
193 if (n > nb_max_retries) {
194 printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
195 nb_exit(1);
198 talloc_free(params0);
200 if (nb_tick()) goto done;
203 rewind(f);
204 goto again;
206 done:
207 fclose(f);
209 if (!read_only && torture_nprocs == 1) {
210 smbcli_deltree(cli->tree, "\\clients");
212 if (!torture_close_connection(cli)) {
213 correct = false;
216 return correct;
220 /* run a test that simulates an approximate netbench client load */
221 bool torture_nbench(struct torture_context *torture)
223 bool correct = true;
224 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
225 struct smbcli_state *cli;
226 const char *p;
228 read_only = torture_setting_bool(torture, "readonly", false);
230 nb_max_retries = torture_setting_int(torture, "nretries", 1);
232 p = torture_setting_string(torture, "timelimit", NULL);
233 if (p && *p) {
234 timelimit = atoi(p);
237 warmup = timelimit / 20;
239 loadfile = torture_setting_string(torture, "loadfile", NULL);
240 if (!loadfile || !*loadfile) {
241 loadfile = "client.txt";
244 if (torture_nprocs > 1) {
245 if (!torture_open_connection(&cli, torture, 0)) {
246 return false;
249 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
250 return false;
254 nbio_shmem(torture_nprocs, timelimit, warmup);
256 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
257 timelimit, loadfile, warmup);
259 /* we need to reset SIGCHLD here as the name resolution
260 library may have changed it. We rely on correct signals
261 from childs in the main torture code which reaps
262 children. This is why smbtorture BENCH-NBENCH was sometimes
263 failing */
264 signal(SIGCHLD, SIG_DFL);
267 signal(SIGALRM, nb_alarm);
268 alarm(1);
269 torture_create_procs(torture, run_netbench, &correct);
270 alarm(0);
272 if (!read_only && torture_nprocs > 1) {
273 smbcli_deltree(cli->tree, "\\clients");
276 printf("\nThroughput %g MB/sec\n", nbio_result());
277 return correct;
280 NTSTATUS torture_nbench_init(void)
282 struct torture_suite *suite =
283 torture_suite_create(
284 talloc_autofree_context(),
285 "BENCH");
287 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
289 suite->description = talloc_strdup(suite, "Benchmarks");
291 torture_register_suite(suite);
292 return NT_STATUS_OK;