root/source4/torture/nbench/nbench.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_reconnect
  2. run_netbench
  3. torture_nbench
  4. torture_nbench_init

   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 
  29 int nbench_line_count = 0;
  30 static int timelimit = 600;
  31 static int warmup;
  32 static const char *loadfile;
  33 static int read_only;
  34 
  35 #define ival(s) strtoll(s, NULL, 0)
  36 
  37 static 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 
  42 static void do_reconnect(struct smbcli_state **cli, struct torture_context *tctx, int client)
     /* [<][>][^][v][top][bottom][index][help] */
  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 */
  57 static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
     /* [<][>][^][v][top][bottom][index][help] */
  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;
  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 
  89 again:
  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                 line[strlen(line)-1] = 0;
  99 
 100                 all_string_sub(line,"client1", cname, sizeof(line));
 101                 
 102                 params = params0 = str_list_make_shell(NULL, line, " ");
 103                 i = str_list_length(params);
 104 
 105                 if (i > 0 && isdigit(params[0][0])) {
 106                         double targett = strtod(params[0], NULL);
 107                         if (target_rate != 0) {
 108                                 nbio_target_rate(target_rate);
 109                         } else {
 110                                 nbio_time_delay(targett);
 111                         }
 112                         params++;
 113                         i--;
 114                 } else if (target_rate != 0) {
 115                         nbio_target_rate(target_rate);
 116                 }
 117 
 118                 if (i < 2 || params[0][0] == '#') continue;
 119 
 120                 if (!strncmp(params[0],"SMB", 3)) {
 121                         printf("ERROR: You are using a dbench 1 load file\n");
 122                         nb_exit(1);
 123                 }
 124 
 125                 if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
 126                     strncmp(params[i-1], "0x", 2) != 0) {
 127                         printf("Badly formed status at line %d\n", nbench_line_count);
 128                         talloc_free(params);
 129                         continue;
 130                 }
 131 
 132                 /* accept numeric or string status codes */
 133                 if (strncmp(params[i-1], "0x", 2) == 0) {
 134                         status = NT_STATUS(strtoul(params[i-1], NULL, 16));
 135                 } else {
 136                         status = nt_status_string_to_code(params[i-1]);
 137                 }
 138 
 139                 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
 140 
 141                 if (!strcmp(params[0],"NTCreateX")) {
 142                         NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]), 
 143                                             ival(params[4]), status));
 144                 } else if (!strcmp(params[0],"Close")) {
 145                         NB_RETRY(nb_close(ival(params[1]), status));
 146                 } else if (!read_only && !strcmp(params[0],"Rename")) {
 147                         NB_RETRY(nb_rename(params[1], params[2], status, n>0));
 148                 } else if (!read_only && !strcmp(params[0],"Unlink")) {
 149                         NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
 150                 } else if (!read_only && !strcmp(params[0],"Deltree")) {
 151                         NB_RETRY(nb_deltree(params[1], n>0));
 152                 } else if (!read_only && !strcmp(params[0],"Rmdir")) {
 153                         NB_RETRY(nb_rmdir(params[1], status, n>0));
 154                 } else if (!read_only && !strcmp(params[0],"Mkdir")) {
 155                         NB_RETRY(nb_mkdir(params[1], status, n>0));
 156                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
 157                         NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
 158                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
 159                         NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
 160                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
 161                         NB_RETRY(nb_qfsinfo(ival(params[1]), status));
 162                 } else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
 163                         NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
 164                 } else if (!strcmp(params[0],"FIND_FIRST")) {
 165                         NB_RETRY(nb_findfirst(params[1], ival(params[2]), 
 166                                               ival(params[3]), ival(params[4]), status));
 167                 } else if (!read_only && !strcmp(params[0],"WriteX")) {
 168                         NB_RETRY(nb_writex(ival(params[1]), 
 169                                            ival(params[2]), ival(params[3]), ival(params[4]),
 170                                            status));
 171                 } else if (!read_only && !strcmp(params[0],"Write")) {
 172                         NB_RETRY(nb_write(ival(params[1]), 
 173                                           ival(params[2]), ival(params[3]), ival(params[4]),
 174                                           status));
 175                 } else if (!strcmp(params[0],"LockX")) {
 176                         NB_RETRY(nb_lockx(ival(params[1]), 
 177                                           ival(params[2]), ival(params[3]), status));
 178                 } else if (!strcmp(params[0],"UnlockX")) {
 179                         NB_RETRY(nb_unlockx(ival(params[1]), 
 180                                             ival(params[2]), ival(params[3]), status));
 181                 } else if (!strcmp(params[0],"ReadX")) {
 182                         NB_RETRY(nb_readx(ival(params[1]), 
 183                                           ival(params[2]), ival(params[3]), ival(params[4]),
 184                                           status));
 185                 } else if (!strcmp(params[0],"Flush")) {
 186                         NB_RETRY(nb_flush(ival(params[1]), status));
 187                 } else if (!strcmp(params[0],"Sleep")) {
 188                         nb_sleep(ival(params[1]), status);
 189                 } else {
 190                         printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
 191                 }
 192 
 193                 if (n > nb_max_retries) {
 194                         printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
 195                         nb_exit(1);
 196                 }
 197 
 198                 talloc_free(params0);
 199                 
 200                 if (nb_tick()) goto done;
 201         }
 202 
 203         rewind(f);
 204         goto again;
 205 
 206 done:
 207         fclose(f);
 208 
 209         if (!read_only && torture_nprocs == 1) {
 210                 smbcli_deltree(cli->tree, "\\clients");
 211         }
 212         if (!torture_close_connection(cli)) {
 213                 correct = false;
 214         }
 215         
 216         return correct;
 217 }
 218 
 219 
 220 /* run a test that simulates an approximate netbench client load */
 221 bool torture_nbench(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 222 {
 223         bool correct = true;
 224         int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
 225         struct smbcli_state *cli;
 226         const char *p;
 227 
 228         read_only = torture_setting_bool(torture, "readonly", false);
 229 
 230         nb_max_retries = torture_setting_int(torture, "nretries", 1);
 231 
 232         p = torture_setting_string(torture, "timelimit", NULL);
 233         if (p && *p) {
 234                 timelimit = atoi(p);
 235         }
 236 
 237         warmup = timelimit / 20;
 238 
 239         loadfile = torture_setting_string(torture, "loadfile", NULL);
 240         if (!loadfile || !*loadfile) {
 241                 loadfile = "client.txt";
 242         }
 243 
 244         if (torture_nprocs > 1) {
 245                 if (!torture_open_connection(&cli, torture, 0)) {
 246                         return false;
 247                 }
 248 
 249                 if (!read_only && !torture_setup_dir(cli, "\\clients")) {
 250                         return false;
 251                 }
 252         }
 253 
 254         nbio_shmem(torture_nprocs, timelimit, warmup);
 255 
 256         printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
 257                timelimit, loadfile, warmup);
 258 
 259         /* we need to reset SIGCHLD here as the name resolution
 260            library may have changed it. We rely on correct signals
 261            from childs in the main torture code which reaps
 262            children. This is why smbtorture BENCH-NBENCH was sometimes
 263            failing */
 264         signal(SIGCHLD, SIG_DFL);
 265 
 266 
 267         signal(SIGALRM, nb_alarm);
 268         alarm(1);
 269         torture_create_procs(torture, run_netbench, &correct);
 270         alarm(0);
 271 
 272         if (!read_only && torture_nprocs > 1) {
 273                 smbcli_deltree(cli->tree, "\\clients");
 274         }
 275 
 276         printf("\nThroughput %g MB/sec\n", nbio_result());
 277         return correct;
 278 }
 279 
 280 NTSTATUS torture_nbench_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 281 {
 282         struct torture_suite *suite = 
 283                 torture_suite_create(
 284                         talloc_autofree_context(),
 285                         "BENCH");
 286 
 287         torture_suite_add_simple_test(suite, "NBENCH", torture_nbench);
 288 
 289         suite->description = talloc_strdup(suite, "Benchmarks");
 290 
 291         torture_register_suite(suite);
 292         return NT_STATUS_OK;
 293 }

/* [<][>][^][v][top][bottom][index][help] */