source: trunk/server/source4/torture/nbench/nbench.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 8.6 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 = 0;
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 = const_str_list(
105 str_list_make_shell(NULL, line, " "));
106 i = str_list_length(params);
107
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);
114 }
115 params++;
116 i--;
117 } else if (target_rate != 0) {
118 nbio_target_rate(target_rate);
119 }
120
121 if (i < 2 || params[0][0] == '#') continue;
122
123 if (!strncmp(params[0],"SMB", 3)) {
124 printf("ERROR: You are using a dbench 1 load file\n");
125 nb_exit(1);
126 }
127
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;
133 }
134
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]);
140 }
141
142 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
143
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]);
194 }
195
196 if (n > nb_max_retries) {
197 printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
198 nb_exit(1);
199 }
200
201 talloc_free(params0);
202
203 if (nb_tick()) goto done;
204 }
205
206 rewind(f);
207 goto again;
208
209done:
210 fclose(f);
211
212 if (!read_only && torture_nprocs == 1) {
213 smbcli_deltree(cli->tree, "\\clients");
214 }
215 if (!torture_close_connection(cli)) {
216 correct = false;
217 }
218
219 return correct;
220}
221
222
223/* run a test that simulates an approximate netbench client load */
224bool torture_nbench(struct torture_context *torture)
225{
226 bool correct = true;
227 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
228 struct smbcli_state *cli;
229 const char *p;
230
231 read_only = torture_setting_bool(torture, "readonly", false);
232
233 nb_max_retries = torture_setting_int(torture, "nretries", 1);
234
235 p = torture_setting_string(torture, "timelimit", NULL);
236 if (p && *p) {
237 timelimit = atoi(p);
238 }
239
240 warmup = timelimit / 20;
241
242 loadfile = torture_setting_string(torture, "loadfile", NULL);
243 if (!loadfile || !*loadfile) {
244 loadfile = "client.txt";
245 }
246
247 if (torture_nprocs > 1) {
248 if (!torture_open_connection(&cli, torture, 0)) {
249 return false;
250 }
251
252 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
253 return false;
254 }
255 }
256
257 nbio_shmem(torture_nprocs, timelimit, warmup);
258
259 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
260 timelimit, loadfile, warmup);
261
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);
268
269
270 signal(SIGALRM, nb_alarm);
271 alarm(1);
272 torture_create_procs(torture, run_netbench, &correct);
273 alarm(0);
274
275 if (!read_only && torture_nprocs > 1) {
276 smbcli_deltree(cli->tree, "\\clients");
277 }
278
279 printf("\nThroughput %g MB/sec\n", nbio_result());
280 return correct;
281}
282
283NTSTATUS torture_nbench_init(void)
284{
285 struct torture_suite *suite = torture_suite_create(
286 talloc_autofree_context(), "bench");
287
288 torture_suite_add_simple_test(suite, "nbench", torture_nbench);
289
290 suite->description = talloc_strdup(suite, "Benchmarks");
291
292 torture_register_suite(suite);
293 return NT_STATUS_OK;
294}
Note: See TracBrowser for help on using the repository browser.