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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libcli/libcli.h"
23 #include "torture/ui.h"
24 #include "torture/util.h"
25 #include "torture/torture.h"
26 #include "system/filesys.h"
27 #include "system/locale.h"
30 #include "torture/nbench/proto.h"
32 int nbench_line_count = 0;
33 static int timelimit = 600;
35 static const char *loadfile;
38 #define ival(s) strtoll(s, NULL, 0)
40 /* run a test that simulates an approximate netbench client load */
41 static BOOL run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
43 int torture_nprocs = lp_parm_int(-1, "torture", "nprocs", 4);
49 double target_rate = lp_parm_double(-1, "torture", "targetrate", 0);
51 if (target_rate != 0 && client == 0) {
52 printf("Targetting %.4f MByte/sec\n", target_rate);
55 if (torture_nprocs == 1) {
56 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
61 nb_setup(cli, client);
63 asprintf(&cname, "client%d", client+1);
65 f = fopen(loadfile, "r");
76 while (fgets(line, sizeof(line)-1, f)) {
78 const char **params0, **params;
82 line[strlen(line)-1] = 0;
84 all_string_sub(line,"client1", cname, sizeof(line));
86 params = params0 = str_list_make_shell(NULL, line, " ");
87 i = str_list_length(params);
89 if (i > 0 && isdigit(params[0][0])) {
90 double targett = strtod(params[0], NULL);
91 if (target_rate != 0) {
92 nbio_target_rate(target_rate);
94 nbio_time_delay(targett);
98 } else if (target_rate != 0) {
99 nbio_target_rate(target_rate);
102 if (i < 2 || params[0][0] == '#') continue;
104 if (!strncmp(params[0],"SMB", 3)) {
105 printf("ERROR: You are using a dbench 1 load file\n");
109 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
110 strncmp(params[i-1], "0x", 2) != 0) {
111 printf("Badly formed status at line %d\n", nbench_line_count);
116 /* accept numeric or string status codes */
117 if (strncmp(params[i-1], "0x", 2) == 0) {
118 status = NT_STATUS(strtoul(params[i-1], NULL, 16));
120 status = nt_status_string_to_code(params[i-1]);
123 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
125 if (!strcmp(params[0],"NTCreateX")) {
126 nb_createx(params[1], ival(params[2]), ival(params[3]),
127 ival(params[4]), status);
128 } else if (!strcmp(params[0],"Close")) {
129 nb_close(ival(params[1]), status);
130 } else if (!read_only && !strcmp(params[0],"Rename")) {
131 nb_rename(params[1], params[2], status);
132 } else if (!read_only && !strcmp(params[0],"Unlink")) {
133 nb_unlink(params[1], ival(params[2]), status);
134 } else if (!read_only && !strcmp(params[0],"Deltree")) {
135 nb_deltree(params[1]);
136 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
137 nb_rmdir(params[1], status);
138 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
139 nb_mkdir(params[1], status);
140 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
141 nb_qpathinfo(params[1], ival(params[2]), status);
142 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
143 nb_qfileinfo(ival(params[1]), ival(params[2]), status);
144 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
145 nb_qfsinfo(ival(params[1]), status);
146 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
147 nb_sfileinfo(ival(params[1]), ival(params[2]), status);
148 } else if (!strcmp(params[0],"FIND_FIRST")) {
149 nb_findfirst(params[1], ival(params[2]),
150 ival(params[3]), ival(params[4]), status);
151 } else if (!read_only && !strcmp(params[0],"WriteX")) {
152 nb_writex(ival(params[1]),
153 ival(params[2]), ival(params[3]), ival(params[4]),
155 } else if (!read_only && !strcmp(params[0],"Write")) {
156 nb_write(ival(params[1]),
157 ival(params[2]), ival(params[3]), ival(params[4]),
159 } else if (!strcmp(params[0],"LockX")) {
160 nb_lockx(ival(params[1]),
161 ival(params[2]), ival(params[3]), status);
162 } else if (!strcmp(params[0],"UnlockX")) {
163 nb_unlockx(ival(params[1]),
164 ival(params[2]), ival(params[3]), status);
165 } else if (!strcmp(params[0],"ReadX")) {
166 nb_readx(ival(params[1]),
167 ival(params[2]), ival(params[3]), ival(params[4]),
169 } else if (!strcmp(params[0],"Flush")) {
170 nb_flush(ival(params[1]), status);
171 } else if (!strcmp(params[0],"Sleep")) {
172 nb_sleep(ival(params[1]), status);
174 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
177 talloc_free(params0);
179 if (nb_tick()) goto done;
188 if (!read_only && torture_nprocs == 1) {
189 smbcli_deltree(cli->tree, "\\clients");
191 if (!torture_close_connection(cli)) {
199 /* run a test that simulates an approximate netbench client load */
200 BOOL torture_nbench(struct torture_context *torture)
203 int torture_nprocs = lp_parm_int(-1, "torture", "nprocs", 4);
204 struct smbcli_state *cli;
207 read_only = lp_parm_bool(-1, "torture", "readonly", False);
209 p = torture_setting_string(torture, "timelimit", NULL);
214 warmup = timelimit / 20;
216 loadfile = torture_setting_string(torture, "loadfile", NULL);
217 if (!loadfile || !*loadfile) {
218 loadfile = "client.txt";
221 if (torture_nprocs > 1) {
222 if (!torture_open_connection(&cli, 0)) {
226 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
231 nbio_shmem(torture_nprocs, timelimit, warmup);
233 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
234 timelimit, loadfile, warmup);
236 /* we need to reset SIGCHLD here as the name resolution
237 library may have changed it. We rely on correct signals
238 from childs in the main torture code which reaps
239 children. This is why smbtorture BENCH-NBENCH was sometimes
241 signal(SIGCHLD, SIG_DFL);
244 signal(SIGALRM, nb_alarm);
246 torture_create_procs(torture, run_netbench, &correct);
249 if (!read_only && torture_nprocs > 1) {
250 smbcli_deltree(cli->tree, "\\clients");
253 printf("\nThroughput %g MB/sec\n", nbio_result());
257 NTSTATUS torture_nbench_init(void)
259 struct torture_suite *suite = torture_suite_create(
260 talloc_autofree_context(),
263 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
265 suite->description = talloc_strdup(suite,
268 torture_register_suite(suite);