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/>.
21 #include "libcli/libcli.h"
22 #include "torture/ui.h"
23 #include "torture/util.h"
24 #include "torture/torture.h"
25 #include "system/filesys.h"
26 #include "system/locale.h"
29 #include "torture/nbench/proto.h"
31 int nbench_line_count = 0;
32 static int timelimit = 600;
34 static const char *loadfile;
37 #define ival(s) strtoll(s, NULL, 0)
39 /* run a test that simulates an approximate netbench client load */
40 static BOOL run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
42 int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
48 double target_rate = lp_parm_double(-1, "torture", "targetrate", 0);
50 if (target_rate != 0 && client == 0) {
51 printf("Targetting %.4f MByte/sec\n", target_rate);
54 if (torture_nprocs == 1) {
55 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
60 nb_setup(cli, client);
62 asprintf(&cname, "client%d", client+1);
64 f = fopen(loadfile, "r");
75 while (fgets(line, sizeof(line)-1, f)) {
77 const char **params0, **params;
81 line[strlen(line)-1] = 0;
83 all_string_sub(line,"client1", cname, sizeof(line));
85 params = params0 = str_list_make_shell(NULL, line, " ");
86 i = str_list_length(params);
88 if (i > 0 && isdigit(params[0][0])) {
89 double targett = strtod(params[0], NULL);
90 if (target_rate != 0) {
91 nbio_target_rate(target_rate);
93 nbio_time_delay(targett);
97 } else if (target_rate != 0) {
98 nbio_target_rate(target_rate);
101 if (i < 2 || params[0][0] == '#') continue;
103 if (!strncmp(params[0],"SMB", 3)) {
104 printf("ERROR: You are using a dbench 1 load file\n");
108 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
109 strncmp(params[i-1], "0x", 2) != 0) {
110 printf("Badly formed status at line %d\n", nbench_line_count);
115 /* accept numeric or string status codes */
116 if (strncmp(params[i-1], "0x", 2) == 0) {
117 status = NT_STATUS(strtoul(params[i-1], NULL, 16));
119 status = nt_status_string_to_code(params[i-1]);
122 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
124 if (!strcmp(params[0],"NTCreateX")) {
125 nb_createx(params[1], ival(params[2]), ival(params[3]),
126 ival(params[4]), status);
127 } else if (!strcmp(params[0],"Close")) {
128 nb_close(ival(params[1]), status);
129 } else if (!read_only && !strcmp(params[0],"Rename")) {
130 nb_rename(params[1], params[2], status);
131 } else if (!read_only && !strcmp(params[0],"Unlink")) {
132 nb_unlink(params[1], ival(params[2]), status);
133 } else if (!read_only && !strcmp(params[0],"Deltree")) {
134 nb_deltree(params[1]);
135 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
136 nb_rmdir(params[1], status);
137 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
138 nb_mkdir(params[1], status);
139 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
140 nb_qpathinfo(params[1], ival(params[2]), status);
141 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
142 nb_qfileinfo(ival(params[1]), ival(params[2]), status);
143 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
144 nb_qfsinfo(ival(params[1]), status);
145 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
146 nb_sfileinfo(ival(params[1]), ival(params[2]), status);
147 } else if (!strcmp(params[0],"FIND_FIRST")) {
148 nb_findfirst(params[1], ival(params[2]),
149 ival(params[3]), ival(params[4]), status);
150 } else if (!read_only && !strcmp(params[0],"WriteX")) {
151 nb_writex(ival(params[1]),
152 ival(params[2]), ival(params[3]), ival(params[4]),
154 } else if (!read_only && !strcmp(params[0],"Write")) {
155 nb_write(ival(params[1]),
156 ival(params[2]), ival(params[3]), ival(params[4]),
158 } else if (!strcmp(params[0],"LockX")) {
159 nb_lockx(ival(params[1]),
160 ival(params[2]), ival(params[3]), status);
161 } else if (!strcmp(params[0],"UnlockX")) {
162 nb_unlockx(ival(params[1]),
163 ival(params[2]), ival(params[3]), status);
164 } else if (!strcmp(params[0],"ReadX")) {
165 nb_readx(ival(params[1]),
166 ival(params[2]), ival(params[3]), ival(params[4]),
168 } else if (!strcmp(params[0],"Flush")) {
169 nb_flush(ival(params[1]), status);
170 } else if (!strcmp(params[0],"Sleep")) {
171 nb_sleep(ival(params[1]), status);
173 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
176 talloc_free(params0);
178 if (nb_tick()) goto done;
187 if (!read_only && torture_nprocs == 1) {
188 smbcli_deltree(cli->tree, "\\clients");
190 if (!torture_close_connection(cli)) {
198 /* run a test that simulates an approximate netbench client load */
199 BOOL torture_nbench(struct torture_context *torture)
202 int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
203 struct smbcli_state *cli;
206 read_only = torture_setting_bool(torture, "readonly", False);
208 p = torture_setting_string(torture, "timelimit", NULL);
213 warmup = timelimit / 20;
215 loadfile = torture_setting_string(torture, "loadfile", NULL);
216 if (!loadfile || !*loadfile) {
217 loadfile = "client.txt";
220 if (torture_nprocs > 1) {
221 if (!torture_open_connection(&cli, 0)) {
225 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
230 nbio_shmem(torture_nprocs, timelimit, warmup);
232 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
233 timelimit, loadfile, warmup);
235 /* we need to reset SIGCHLD here as the name resolution
236 library may have changed it. We rely on correct signals
237 from childs in the main torture code which reaps
238 children. This is why smbtorture BENCH-NBENCH was sometimes
240 signal(SIGCHLD, SIG_DFL);
243 signal(SIGALRM, nb_alarm);
245 torture_create_procs(torture, run_netbench, &correct);
248 if (!read_only && torture_nprocs > 1) {
249 smbcli_deltree(cli->tree, "\\clients");
252 printf("\nThroughput %g MB/sec\n", nbio_result());
256 NTSTATUS torture_nbench_init(void)
258 struct torture_suite *suite = torture_suite_create(
259 talloc_autofree_context(),
262 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
264 suite->description = talloc_strdup(suite,
267 torture_register_suite(suite);