source: branches/samba-3.5.x/source4/torture/nbench/nbench.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

File size: 8.3 KB
Line 
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 3 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, see <http://www.gnu.org/licenses/>.
18*/
19
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
27#include "torture/nbench/proto.h"
28
29int nbench_line_count = 0;
30static int timelimit = 600;
31static int warmup;
32static const char *loadfile;
33static int read_only;
34
35#define ival(s) strtoll(s, NULL, 0)
36
37static unsigned long nb_max_retries;
38
39#define NB_RETRY(op) \
40 for (n=0;n<=nb_max_retries && !op;n++) do_reconnect(&cli, tctx, client)
41
42static void do_reconnect(struct smbcli_state **cli, struct torture_context *tctx, int client)
43{
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;
50 }
51 }
52 printf("[%d] Failed to reconnect client %d\n", nbench_line_count, client);
53 nb_exit(1);
54}
55
56/* run a test that simulates an approximate netbench client load */
57static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
58{
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;
67
68 if (target_rate != 0 && client == 0) {
69 printf("Targetting %.4f MByte/sec\n", target_rate);
70 }
71
72 nb_setup(cli, client);
73
74 if (torture_nprocs == 1) {
75 if (!read_only) {
76 NB_RETRY(torture_setup_dir(cli, "\\clients"));
77 }
78 }
79
80 asprintf(&cname, "client%d", client+1);
81
82 f = fopen(loadfile, "r");
83
84 if (!f) {
85 perror(loadfile);
86 return false;
87 }
88
89again:
90 nbio_time_reset();
91
92 while (fgets(line, sizeof(line)-1, f)) {
93 NTSTATUS status;
94 const char **params0, **params;
95
96 nbench_line_count++;
97
98 if ((strlen(line) > 0) && line[strlen(line)-1] == '\n') {
99 line[strlen(line)-1] = 0;
100 }
101
102 all_string_sub(line,"client1", cname, sizeof(line));
103
104 params = params0 = str_list_make_shell(NULL, line, " ");
105 i = str_list_length(params);
106
107 if (i > 0 && isdigit(params[0][0])) {
108 double targett = strtod(params[0], NULL);
109 if (target_rate != 0) {
110 nbio_target_rate(target_rate);
111 } else {
112 nbio_time_delay(targett);
113 }
114 params++;
115 i--;
116 } else if (target_rate != 0) {
117 nbio_target_rate(target_rate);
118 }
119
120 if (i < 2 || params[0][0] == '#') continue;
121
122 if (!strncmp(params[0],"SMB", 3)) {
123 printf("ERROR: You are using a dbench 1 load file\n");
124 nb_exit(1);
125 }
126
127 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
128 strncmp(params[i-1], "0x", 2) != 0) {
129 printf("Badly formed status at line %d\n", nbench_line_count);
130 talloc_free(params);
131 continue;
132 }
133
134 /* accept numeric or string status codes */
135 if (strncmp(params[i-1], "0x", 2) == 0) {
136 status = NT_STATUS(strtoul(params[i-1], NULL, 16));
137 } else {
138 status = nt_status_string_to_code(params[i-1]);
139 }
140
141 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
142
143 if (!strcmp(params[0],"NTCreateX")) {
144 NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]),
145 ival(params[4]), status));
146 } else if (!strcmp(params[0],"Close")) {
147 NB_RETRY(nb_close(ival(params[1]), status));
148 } else if (!read_only && !strcmp(params[0],"Rename")) {
149 NB_RETRY(nb_rename(params[1], params[2], status, n>0));
150 } else if (!read_only && !strcmp(params[0],"Unlink")) {
151 NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
152 } else if (!read_only && !strcmp(params[0],"Deltree")) {
153 NB_RETRY(nb_deltree(params[1], n>0));
154 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
155 NB_RETRY(nb_rmdir(params[1], status, n>0));
156 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
157 NB_RETRY(nb_mkdir(params[1], status, n>0));
158 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
159 NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
160 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
161 NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
162 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
163 NB_RETRY(nb_qfsinfo(ival(params[1]), status));
164 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
165 NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
166 } else if (!strcmp(params[0],"FIND_FIRST")) {
167 NB_RETRY(nb_findfirst(params[1], ival(params[2]),
168 ival(params[3]), ival(params[4]), status));
169 } else if (!read_only && !strcmp(params[0],"WriteX")) {
170 NB_RETRY(nb_writex(ival(params[1]),
171 ival(params[2]), ival(params[3]), ival(params[4]),
172 status));
173 } else if (!read_only && !strcmp(params[0],"Write")) {
174 NB_RETRY(nb_write(ival(params[1]),
175 ival(params[2]), ival(params[3]), ival(params[4]),
176 status));
177 } else if (!strcmp(params[0],"LockX")) {
178 NB_RETRY(nb_lockx(ival(params[1]),
179 ival(params[2]), ival(params[3]), status));
180 } else if (!strcmp(params[0],"UnlockX")) {
181 NB_RETRY(nb_unlockx(ival(params[1]),
182 ival(params[2]), ival(params[3]), status));
183 } else if (!strcmp(params[0],"ReadX")) {
184 NB_RETRY(nb_readx(ival(params[1]),
185 ival(params[2]), ival(params[3]), ival(params[4]),
186 status));
187 } else if (!strcmp(params[0],"Flush")) {
188 NB_RETRY(nb_flush(ival(params[1]), status));
189 } else if (!strcmp(params[0],"Sleep")) {
190 nb_sleep(ival(params[1]), status);
191 } else {
192 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
193 }
194
195 if (n > nb_max_retries) {
196 printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
197 nb_exit(1);
198 }
199
200 talloc_free(params0);
201
202 if (nb_tick()) goto done;
203 }
204
205 rewind(f);
206 goto again;
207
208done:
209 fclose(f);
210
211 if (!read_only && torture_nprocs == 1) {
212 smbcli_deltree(cli->tree, "\\clients");
213 }
214 if (!torture_close_connection(cli)) {
215 correct = false;
216 }
217
218 return correct;
219}
220
221
222/* run a test that simulates an approximate netbench client load */
223bool torture_nbench(struct torture_context *torture)
224{
225 bool correct = true;
226 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
227 struct smbcli_state *cli;
228 const char *p;
229
230 read_only = torture_setting_bool(torture, "readonly", false);
231
232 nb_max_retries = torture_setting_int(torture, "nretries", 1);
233
234 p = torture_setting_string(torture, "timelimit", NULL);
235 if (p && *p) {
236 timelimit = atoi(p);
237 }
238
239 warmup = timelimit / 20;
240
241 loadfile = torture_setting_string(torture, "loadfile", NULL);
242 if (!loadfile || !*loadfile) {
243 loadfile = "client.txt";
244 }
245
246 if (torture_nprocs > 1) {
247 if (!torture_open_connection(&cli, torture, 0)) {
248 return false;
249 }
250
251 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
252 return false;
253 }
254 }
255
256 nbio_shmem(torture_nprocs, timelimit, warmup);
257
258 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
259 timelimit, loadfile, warmup);
260
261 /* we need to reset SIGCHLD here as the name resolution
262 library may have changed it. We rely on correct signals
263 from childs in the main torture code which reaps
264 children. This is why smbtorture BENCH-NBENCH was sometimes
265 failing */
266 signal(SIGCHLD, SIG_DFL);
267
268
269 signal(SIGALRM, nb_alarm);
270 alarm(1);
271 torture_create_procs(torture, run_netbench, &correct);
272 alarm(0);
273
274 if (!read_only && torture_nprocs > 1) {
275 smbcli_deltree(cli->tree, "\\clients");
276 }
277
278 printf("\nThroughput %g MB/sec\n", nbio_result());
279 return correct;
280}
281
282NTSTATUS torture_nbench_init(void)
283{
284 struct torture_suite *suite =
285 torture_suite_create(
286 talloc_autofree_context(),
287 "BENCH");
288
289 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
290
291 suite->description = talloc_strdup(suite, "Benchmarks");
292
293 torture_register_suite(suite);
294 return NT_STATUS_OK;
295}
Note: See TracBrowser for help on using the repository browser.