added full netbench simulation in smbtorture. It now reads a 4MB load
authorAndrew Tridgell <tridge@samba.org>
Sat, 15 May 1999 06:20:33 +0000 (06:20 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 15 May 1999 06:20:33 +0000 (06:20 +0000)
description file that was derived from a packet capture of a real
netbench run. That file describes every SMB operation that a netbench
client performs on the wire and smbtorture uses that to simulate any
number of simultaneous netbench clients, giving results on the same
scale that netbench does.

the nice thing is that it all seems to work. I'm actually getting
results pretty close to what a real netbench lab gets.

source/Makefile.in
source/include/client.h
source/include/proto.h
source/utils/nbio.c [new file with mode: 0644]
source/utils/torture.c

index 09d5c0cfe6f65d61db433304c4efa3af74f4b0a4..5fe566845237e2043271d2d72cb5dacb4ca96618 100644 (file)
@@ -231,7 +231,7 @@ UMOUNT_OBJ = client/smbumount.o \
 NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \
                 $(LIBSMB_OBJ) $(LIB_OBJ)
 
-SMBTORTURE_OBJ = utils/torture.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+SMBTORTURE_OBJ = utils/torture.o utils/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
                  $(UBIQX_OBJ) $(LIB_OBJ)
 
 RPCTORTURE_OBJ = utils/rpctorture.o \
@@ -250,7 +250,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
                  $(UBIQX_OBJ) $(LIB_OBJ)
 
 PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
-           $(RPCCLIENT_OBJ) $(SMBWRAPPER_OBJ)
+           $(RPCCLIENT_OBJ) $(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ)
 
 PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
 PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
index 417db1f25754ead8e67b3e487991d388fbae107a..876dca8429dc509a08444f3877f383fcd6eda6ba 100644 (file)
@@ -27,7 +27,7 @@
 /* the client asks for a smaller buffer to save ram and also to get more
    overlap on the wire. This size gives us a nice read/write size, which
    will be a multiple of the page size on almost any system */
-#define CLI_BUFFER_SIZE (0x4400)
+#define CLI_BUFFER_SIZE (0xFFFF)
 
 /*
  * These definitions depend on smb.h
index a1a10df4a4c432f7cd73ab4a4bea9a201d56dfc5..6892f706b516c4895ade8b55b129471eeb7e0f34 100644 (file)
@@ -2735,6 +2735,23 @@ int smbw_stat_printjob(struct smbw_server *srv,char *path,
 int smbw_fstat(int fd, struct stat *st);
 int smbw_stat(const char *fname, struct stat *st);
 
+/*The following definitions come from  utils/nbio.c  */
+
+void nb_setup(struct cli_state *cli);
+void nb_unlink(char *fname);
+void nb_open(char *fname, int handle, int size);
+void nb_write(int handle, int size, int offset);
+void nb_read(int handle, int size, int offset);
+void nb_close(int handle);
+void nb_mkdir(char *fname);
+void nb_rmdir(char *fname);
+void nb_rename(char *old, char *new);
+void nb_stat(char *fname, int size);
+void nb_create(char *fname, int size);
+
+/*The following definitions come from  utils/torture.c  */
+
+
 /*The following definitions come from  web/cgi.c  */
 
 void cgi_load_variables(FILE *f1);
diff --git a/source/utils/nbio.c b/source/utils/nbio.c
new file mode 100644 (file)
index 0000000..4b36984
--- /dev/null
@@ -0,0 +1,234 @@
+#define NBDEBUG 0
+
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB torture tester
+   Copyright (C) Andrew Tridgell 1997-1998
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+#define MAX_FILES 1000
+
+static char buf[70000];
+extern int line_count;
+
+static struct {
+       int fd;
+       int handle;
+} ftable[MAX_FILES];
+
+static struct cli_state *c;
+
+static int sigsegv(int sig)
+{
+       char line[200];
+       printf("segv at line %d\n", line_count);
+       slprintf(line, sizeof(line), "/usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d", 
+               getpid(), getpid());
+       system(line);
+       exit(1);
+}
+
+void nb_setup(struct cli_state *cli)
+{
+       signal(SIGSEGV, sigsegv);
+       c = cli;
+}
+
+
+void nb_unlink(char *fname)
+{
+       strupper(fname);
+
+       if (!cli_unlink(c, fname)) {
+#if NBDEBUG
+               printf("(%d) unlink %s failed (%s)\n", 
+                      line_count, fname, cli_errstr(c));
+#endif
+       }
+}
+
+void nb_open(char *fname, int handle, int size)
+{
+       int fd, i;
+       int flags = O_RDWR|O_CREAT;
+       size_t st_size;
+       static int count;
+
+       strupper(fname);
+
+       if (size == 0) flags |= O_TRUNC;
+
+       fd = cli_open(c, fname, flags, DENY_NONE);
+       if (fd == -1) {
+#if NBDEBUG
+               printf("(%d) open %s failed for handle %d (%s)\n", 
+                      line_count, fname, handle, cli_errstr(c));
+#endif
+               return;
+       }
+       cli_getattrE(c, fd, NULL, &st_size, NULL, NULL, NULL);
+       if (size > st_size) {
+#if NBDEBUG
+               printf("(%d) needs expanding %s to %d from %d\n", 
+                      line_count, fname, size, (int)st_size);
+#endif
+       } else if (size < st_size) {
+#if NBDEBUG
+               printf("(%d) needs truncating %s to %d from %d\n", 
+                      line_count, fname, size, (int)st_size);
+#endif
+       }
+       for (i=0;i<MAX_FILES;i++) {
+               if (ftable[i].handle == 0) break;
+       }
+       if (i == MAX_FILES) {
+               printf("file table full for %s\n", fname);
+               exit(1);
+       }
+       ftable[i].handle = handle;
+       ftable[i].fd = fd;
+       if (count++ % 100 == 0) {
+               printf(".");
+       }
+}
+
+void nb_write(int handle, int size, int offset)
+{
+       int i;
+
+       if (buf[0] == 0) memset(buf, 1, sizeof(buf));
+
+       for (i=0;i<MAX_FILES;i++) {
+               if (ftable[i].handle == handle) break;
+       }
+       if (i == MAX_FILES) {
+#if NBDEBUG
+               printf("(%d) nb_write: handle %d was not open size=%d ofs=%d\n", 
+                      line_count, handle, size, offset);
+#endif
+               return;
+       }
+       if (cli_smbwrite(c, ftable[i].fd, buf, offset, size) != size) {
+               printf("(%d) write failed on handle %d\n", 
+                      line_count, handle);
+       }
+}
+
+void nb_read(int handle, int size, int offset)
+{
+       int i, ret;
+
+       for (i=0;i<MAX_FILES;i++) {
+               if (ftable[i].handle == handle) break;
+       }
+       if (i == MAX_FILES) {
+               printf("(%d) nb_read: handle %d was not open size=%d ofs=%d\n", 
+                      line_count, handle, size, offset);
+               return;
+       }
+       if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != size) {
+#if NBDEBUG
+               printf("(%d) read failed on handle %d ofs=%d size=%d res=%d\n", 
+                      line_count, handle, offset, size, ret);
+#endif
+       }
+}
+
+void nb_close(int handle)
+{
+       int i;
+       for (i=0;i<MAX_FILES;i++) {
+               if (ftable[i].handle == handle) break;
+       }
+       if (i == MAX_FILES) {
+               printf("(%d) nb_close: handle %d was not open\n", 
+                      line_count, handle);
+               return;
+       }
+       cli_close(c, ftable[i].fd);
+       ftable[i].handle = 0;
+}
+
+void nb_mkdir(char *fname)
+{
+       strupper(fname);
+
+       if (!cli_mkdir(c, fname)) {
+#if NBDEBUG
+               printf("mkdir %s failed (%s)\n", 
+                      fname, cli_errstr(c));
+#endif
+       }
+}
+
+void nb_rmdir(char *fname)
+{
+       strupper(fname);
+
+       if (!cli_rmdir(c, fname)) {
+#if NBDEBUG
+               printf("rmdir %s failed (%s)\n", 
+                      fname, cli_errstr(c));
+#endif
+       }
+}
+
+void nb_rename(char *old, char *new)
+{
+       strupper(old);
+       strupper(new);
+
+       if (!cli_rename(c, old, new)) {
+#if NBDEBUG
+               printf("rename %s %s failed (%s)\n", 
+                      old, new, cli_errstr(c));
+#endif
+       }
+}
+
+
+void nb_stat(char *fname, int size)
+{
+       size_t st_size;
+
+       strupper(fname);
+
+       if (!cli_getatr(c, fname, NULL, &st_size, NULL)) {
+#if NBDEBUG
+               printf("(%d) nb_stat: %s size=%d %s\n", 
+                      line_count, fname, size, cli_errstr(c));
+#endif
+               return;
+       }
+       if (st_size != size) {
+#if NBDEBUG
+               printf("(%d) nb_stat: %s wrong size %d %d\n", 
+                      line_count, fname, (int)st_size, size);
+#endif
+       }
+}
+
+void nb_create(char *fname, int size)
+{
+       nb_open(fname, 5000, size);
+       nb_close(5000);
+}
index 382df9c0e817b49f1acbd98ae13d44560f36eda8..bb550796b238ba94b6854ce464abc376d518e2f9 100644 (file)
@@ -30,7 +30,7 @@ static int nprocs=1, numops=100;
 static pid_t master_pid;
 static struct cli_state current_cli;
 
-static double create_procs(void (*fn)(void));
+static double create_procs(void (*fn)(int ));
 
 
 static struct timeval tp1,tp2;
@@ -266,63 +266,102 @@ static void run_torture(void)
        close_connection(&cli);
 }
 
-static int nbsize1, nbsize2, nbprob1;
+int line_count = 0;
 
 /* run a test that simulates an approximate netbench client load */
-static void run_netbench(void)
+static void run_netbench(int client)
 {
        struct cli_state cli;
-       int fnum, i;
-       int pid = getpid();
-       size_t size;
-       char buf[8192];
+       int i;
        fstring fname;
+       pstring line;
+       char cname[20];
+       FILE *f;
+       char *params[20];
 
        cli = current_cli;
 
        cli_sockopt(&cli, sockops);
 
-       slprintf(fname, sizeof(fname) - 1, "\\c%05d", pid);
+       nb_setup(&cli);
 
-       cli_mkdir(&cli, fname);
+       slprintf(cname,sizeof(fname), "CLIENT%d", client);
 
-       for (i=0;i<numops;i++) {
-               slprintf(fname, sizeof(fname) - 1, "\\c%05d\\%d.doc", pid, i);
+       f = fopen("client.txt", "r");
 
-               fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
-               if (fnum == -1) {
-                       printf("open failed (%s)\n", cli_errstr(&cli));
-                       break;
-               }
+       if (!f) {
+               perror("client.txt");
+               return;
+       }
 
-               size = 0;
-               while (size < 256*1024) {
-                       int s;
-                       if (((unsigned)random()) % 100 > nbprob1) {
-                               s = nbsize2;
-                       } else {
-                               s = nbsize1;
+       while (fgets(line, sizeof(line)-1, f)) {
+               line_count++;
+
+               line[strlen(line)-1] = 0;
+
+               all_string_sub(line,"CLIENT1", cname);
+               
+               for (i=0;i<20;i++) params[i] = "";
+
+               /* parse the command parameters */
+               params[0] = strtok(line," ");
+               i = 0;
+               while (params[i]) params[++i] = strtok(NULL," ");
+
+               params[i] = "";
+
+               if (i < 2) continue;
+
+               if (strcmp(params[1],"REQUEST") == 0) {
+                       if (!strcmp(params[0],"SMBopenX")) {
+                               fstrcpy(fname, params[5]);
+                       } else if (!strcmp(params[0],"SMBclose")) {
+                               nb_close(atoi(params[3]));
+                       } else if (!strcmp(params[0],"SMBmkdir")) {
+                               nb_mkdir(params[3]);
+                       } else if (!strcmp(params[0],"CREATE")) {
+                               nb_create(params[3], atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBrmdir")) {
+                               nb_rmdir(params[3]);
+                       } else if (!strcmp(params[0],"SMBunlink")) {
+                               fstrcpy(fname, params[3]);
+                       } else if (!strcmp(params[0],"SMBmv")) {
+                               nb_rename(params[3], params[5]);
+                       } else if (!strcmp(params[0],"SMBgetatr")) {
+                               fstrcpy(fname, params[3]);
+                       } else if (!strcmp(params[0],"SMBwrite")) {
+                               nb_write(atoi(params[3]), 
+                                        atoi(params[5]), atoi(params[7]));
+                       } else if (!strcmp(params[0],"SMBwritebraw")) {
+                               nb_write(atoi(params[3]), 
+                                        atoi(params[7]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBreadbraw")) {
+                               nb_read(atoi(params[3]), 
+                                        atoi(params[7]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBread")) {
+                               nb_read(atoi(params[3]), 
+                                        atoi(params[5]), atoi(params[7]));
                        }
-
-                       if (cli_smbwrite(&cli, fnum, buf, size, s) != s) {
-                               printf("write failed (%s)\n", cli_errstr(&cli));
-                               break;
+               } else {
+                       if (!strcmp(params[0],"SMBopenX")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_open(fname, atoi(params[3]), atoi(params[5]));
+                       } else if (!strcmp(params[0],"SMBgetatr")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_stat(fname, atoi(params[3]));
+                       } else if (!strcmp(params[0],"SMBunlink")) {
+                               if (!strncmp(params[2], "ERR", 3)) continue;
+                               nb_unlink(fname);
                        }
-                       size += s;
                }
-               cli_close(&cli, fnum);
-               printf("."); fflush(stdout);
        }
+       fclose(f);
 
-       printf("+"); fflush(stdout);
-
-       for (i=0;i<numops;i++) {
-               slprintf(fname, sizeof(fname) - 1, "\\c%05d\\%d.doc", pid, i);
-               cli_unlink(&cli, fname);
-       }
+       slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
+       rmdir(fname);
+       rmdir("CLIENTS");
 
-       slprintf(fname, sizeof(fname) - 1, "\\c%05d", pid);
-       cli_rmdir(&cli, fname);
+       printf("+");    
 
        close_connection(&cli);
 }
@@ -332,22 +371,18 @@ static void run_netbench(void)
 static void run_nbw95(void)
 {
        double t;
-       nbsize1 = 4096;
-       nbsize2 = 0;
-       nbprob1 = 100;
        t = create_procs(run_netbench);
-       printf("Throughput %g MB/sec\n", nprocs*numops*256.0/(t*1024));
+       printf("Throughput %g MB/sec (NB=%g MB/sec  %g MBit/sec)\n", 
+              132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
 }
 
 /* run a test that simulates an approximate netbench wNT client load */
 static void run_nbwnt(void)
 {
        double t;
-       nbsize1 = 4296;
-       nbsize2 = 0;
-       nbprob1 = 67;
        t = create_procs(run_netbench);
-       printf("Throughput %g MB/sec\n", nprocs*numops*256.0/(t*1024));
+       printf("Throughput %g MB/sec (NB=%g MB/sec  %g MBit/sec)\n", 
+              132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
 }
 
 
@@ -1051,7 +1086,7 @@ static void run_trans2test(void)
        printf("trans2 test finished\n");
 }
 
-static double create_procs(void (*fn)(void))
+static double create_procs(void (*fn)(int ))
 {
        int i, status;
        volatile int *child_status;
@@ -1090,7 +1125,7 @@ static double create_procs(void (*fn)(void))
 
                        while (child_status[i]) msleep(2);
 
-                       fn();
+                       fn(i);
                        _exit(0);
                }
        }