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);
50 if (torture_nprocs == 1) {
51 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
56 nb_setup(cli, client);
58 asprintf(&cname, "client%d", client+1);
60 f = fopen(loadfile, "r");
71 while (fgets(line, sizeof(line)-1, f)) {
73 const char **params0, **params;
77 line[strlen(line)-1] = 0;
79 all_string_sub(line,"client1", cname, sizeof(line));
81 params = params0 = str_list_make_shell(NULL, line, " ");
82 i = str_list_length(params);
84 if (i > 0 && isdigit(params[0][0])) {
85 double targett = strtod(params[0], NULL);
86 nbio_time_delay(targett);
91 if (i < 2 || params[0][0] == '#') continue;
93 if (!strncmp(params[0],"SMB", 3)) {
94 printf("ERROR: You are using a dbench 1 load file\n");
98 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
99 printf("Badly formed status at line %d\n", nbench_line_count);
104 status = nt_status_string_to_code(params[i-1]);
106 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
108 if (!strcmp(params[0],"NTCreateX")) {
109 nb_createx(params[1], ival(params[2]), ival(params[3]),
110 ival(params[4]), status);
111 } else if (!strcmp(params[0],"Close")) {
112 nb_close(ival(params[1]), status);
113 } else if (!read_only && !strcmp(params[0],"Rename")) {
114 nb_rename(params[1], params[2], status);
115 } else if (!read_only && !strcmp(params[0],"Unlink")) {
116 nb_unlink(params[1], ival(params[2]), status);
117 } else if (!read_only && !strcmp(params[0],"Deltree")) {
118 nb_deltree(params[1]);
119 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
120 nb_rmdir(params[1], status);
121 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
122 nb_mkdir(params[1], status);
123 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
124 nb_qpathinfo(params[1], ival(params[2]), status);
125 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
126 nb_qfileinfo(ival(params[1]), ival(params[2]), status);
127 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
128 nb_qfsinfo(ival(params[1]), status);
129 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
130 nb_sfileinfo(ival(params[1]), ival(params[2]), status);
131 } else if (!strcmp(params[0],"FIND_FIRST")) {
132 nb_findfirst(params[1], ival(params[2]),
133 ival(params[3]), ival(params[4]), status);
134 } else if (!read_only && !strcmp(params[0],"WriteX")) {
135 nb_writex(ival(params[1]),
136 ival(params[2]), ival(params[3]), ival(params[4]),
138 } else if (!read_only && !strcmp(params[0],"Write")) {
139 nb_write(ival(params[1]),
140 ival(params[2]), ival(params[3]), ival(params[4]),
142 } else if (!strcmp(params[0],"LockX")) {
143 nb_lockx(ival(params[1]),
144 ival(params[2]), ival(params[3]), status);
145 } else if (!strcmp(params[0],"UnlockX")) {
146 nb_unlockx(ival(params[1]),
147 ival(params[2]), ival(params[3]), status);
148 } else if (!strcmp(params[0],"ReadX")) {
149 nb_readx(ival(params[1]),
150 ival(params[2]), ival(params[3]), ival(params[4]),
152 } else if (!strcmp(params[0],"Flush")) {
153 nb_flush(ival(params[1]), status);
154 } else if (!strcmp(params[0],"Sleep")) {
155 nb_sleep(ival(params[1]), status);
157 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
160 talloc_free(params0);
162 if (nb_tick()) goto done;
171 if (!read_only && torture_nprocs == 1) {
172 smbcli_deltree(cli->tree, "\\clients");
174 if (!torture_close_connection(cli)) {
182 /* run a test that simulates an approximate netbench client load */
183 BOOL torture_nbench(struct torture_context *torture)
186 int torture_nprocs = lp_parm_int(-1, "torture", "nprocs", 4);
187 struct smbcli_state *cli;
190 read_only = lp_parm_bool(-1, "torture", "readonly", False);
192 p = torture_setting_string(torture, "timelimit", NULL);
197 warmup = timelimit / 20;
199 loadfile = torture_setting_string(torture, "loadfile", NULL);
200 if (!loadfile || !*loadfile) {
201 loadfile = "client.txt";
204 if (torture_nprocs > 1) {
205 if (!torture_open_connection(&cli, 0)) {
209 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
214 nbio_shmem(torture_nprocs, timelimit, warmup);
216 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
217 timelimit, loadfile, warmup);
219 /* we need to reset SIGCHLD here as the name resolution
220 library may have changed it. We rely on correct signals
221 from childs in the main torture code which reaps
222 children. This is why smbtorture BENCH-NBENCH was sometimes
224 signal(SIGCHLD, SIG_DFL);
227 signal(SIGALRM, nb_alarm);
229 torture_create_procs(torture, run_netbench, &correct);
232 if (!read_only && torture_nprocs > 1) {
233 smbcli_deltree(cli->tree, "\\clients");
236 printf("\nThroughput %g MB/sec\n", nbio_result());
240 NTSTATUS torture_nbench_init(void)
242 struct torture_suite *suite = torture_suite_create(
243 talloc_autofree_context(),
246 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
248 suite->description = talloc_strdup(suite,
251 torture_register_suite(suite);