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"
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) strtol(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 = 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");
68 while (fgets(line, sizeof(line)-1, f)) {
73 line[strlen(line)-1] = 0;
75 all_string_sub(line,"client1", cname, sizeof(line));
77 params = str_list_make_shell(NULL, line, " ");
78 i = str_list_length(params);
80 if (i < 2 || params[0][0] == '#') continue;
82 if (!strncmp(params[0],"SMB", 3)) {
83 printf("ERROR: You are using a dbench 1 load file\n");
87 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0) {
88 printf("Badly formed status at line %d\n", nbench_line_count);
93 status = nt_status_string_to_code(params[i-1]);
95 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
97 if (!strcmp(params[0],"NTCreateX")) {
98 nb_createx(params[1], ival(params[2]), ival(params[3]),
99 ival(params[4]), status);
100 } else if (!strcmp(params[0],"Close")) {
101 nb_close(ival(params[1]), status);
102 } else if (!read_only && !strcmp(params[0],"Rename")) {
103 nb_rename(params[1], params[2], status);
104 } else if (!read_only && !strcmp(params[0],"Unlink")) {
105 nb_unlink(params[1], ival(params[2]), status);
106 } else if (!read_only && !strcmp(params[0],"Deltree")) {
107 nb_deltree(params[1]);
108 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
109 nb_rmdir(params[1], status);
110 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
111 nb_mkdir(params[1], status);
112 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
113 nb_qpathinfo(params[1], ival(params[2]), status);
114 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
115 nb_qfileinfo(ival(params[1]), ival(params[2]), status);
116 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
117 nb_qfsinfo(ival(params[1]), status);
118 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
119 nb_sfileinfo(ival(params[1]), ival(params[2]), status);
120 } else if (!strcmp(params[0],"FIND_FIRST")) {
121 nb_findfirst(params[1], ival(params[2]),
122 ival(params[3]), ival(params[4]), status);
123 } else if (!read_only && !strcmp(params[0],"WriteX")) {
124 nb_writex(ival(params[1]),
125 ival(params[2]), ival(params[3]), ival(params[4]),
127 } else if (!read_only && !strcmp(params[0],"Write")) {
128 nb_write(ival(params[1]),
129 ival(params[2]), ival(params[3]), ival(params[4]),
131 } else if (!strcmp(params[0],"LockX")) {
132 nb_lockx(ival(params[1]),
133 ival(params[2]), ival(params[3]), status);
134 } else if (!strcmp(params[0],"UnlockX")) {
135 nb_unlockx(ival(params[1]),
136 ival(params[2]), ival(params[3]), status);
137 } else if (!strcmp(params[0],"ReadX")) {
138 nb_readx(ival(params[1]),
139 ival(params[2]), ival(params[3]), ival(params[4]),
141 } else if (!strcmp(params[0],"Flush")) {
142 nb_flush(ival(params[1]), status);
143 } else if (!strcmp(params[0],"Sleep")) {
144 nb_sleep(ival(params[1]), status);
146 printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
151 if (nb_tick()) goto done;
160 if (!read_only && torture_nprocs == 1) {
161 smbcli_deltree(cli->tree, "\\clients");
163 if (!torture_close_connection(cli)) {
171 /* run a test that simulates an approximate netbench client load */
172 BOOL torture_nbench(struct torture_context *torture)
175 int torture_nprocs = lp_parm_int(-1, "torture", "nprocs", 4);
176 struct smbcli_state *cli;
179 read_only = lp_parm_bool(-1, "torture", "readonly", False);
181 p = torture_setting_string(torture, "timelimit", NULL);
186 warmup = timelimit / 20;
188 loadfile = torture_setting_string(torture, "loadfile", NULL);
189 if (!loadfile || !*loadfile) {
190 loadfile = "client.txt";
193 if (torture_nprocs > 1) {
194 if (!torture_open_connection(&cli, 0)) {
198 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
203 nbio_shmem(torture_nprocs, timelimit, warmup);
205 printf("Running for %d seconds with load '%s' and warmup %d secs\n",
206 timelimit, loadfile, warmup);
208 /* we need to reset SIGCHLD here as the name resolution
209 library may have changed it. We rely on correct signals
210 from childs in the main torture code which reaps
211 children. This is why smbtorture BENCH-NBENCH was sometimes
213 signal(SIGCHLD, SIG_DFL);
216 signal(SIGALRM, nb_alarm);
218 torture_create_procs(torture, run_netbench, &correct);
221 if (!read_only && torture_nprocs > 1) {
222 smbcli_deltree(cli->tree, "\\clients");
225 printf("\nThroughput %g MB/sec\n", nbio_result());
229 NTSTATUS torture_nbench_init(void)
231 struct torture_suite *suite = torture_suite_create(
232 talloc_autofree_context(),
235 torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
237 suite->description = talloc_strdup(suite,
240 torture_register_suite(suite);