[SCM] Samba Shared Repository - branch master updated - 9915045a453eb90dfa768af988fbf01d0c72f2a8

Volker Lendecke vlendec at samba.org
Fri Dec 19 22:46:38 GMT 2008


The branch, master has been updated
       via  9915045a453eb90dfa768af988fbf01d0c72f2a8 (commit)
       via  32a7ecf5ce3ee7d4abb18348531252a2a7ea48ff (commit)
      from  9f31468bd37aba42ab1fa39a90174bd2d14214b5 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9915045a453eb90dfa768af988fbf01d0c72f2a8
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 19 23:41:19 2008 +0100

    Add a torture test simulating Windows write behaviour
    
    Jeremy, enjoy :-)

commit 32a7ecf5ce3ee7d4abb18348531252a2a7ea48ff
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 19 23:33:55 2008 +0100

    Make smbclient "put" use cli_push
    
    This should fill the TCP socket even beyond the smbclient io_bufsize, very much
    like smbclient "get" should do it since 3.2

-----------------------------------------------------------------------

Summary of changes:
 source3/client/client.c   |   68 +++++++++++++++++--------------------
 source3/torture/torture.c |   82 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 112 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/client/client.c b/source3/client/client.c
index c88b918..03bc15c 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -190,7 +190,7 @@ static int writefile(int f, char *b, int n)
  number read. read approx n bytes.
 ****************************************************************************/
 
-static int readfile(char *b, int n, XFILE *f)
+static int readfile(uint8_t *b, int n, XFILE *f)
 {
 	int i;
 	int c;
@@ -214,6 +214,25 @@ static int readfile(char *b, int n, XFILE *f)
 	return(i);
 }
 
+struct push_state {
+	XFILE *f;
+	SMB_OFF_T nread;
+};
+
+static size_t push_source(uint8_t *buf, size_t n, void *priv)
+{
+	struct push_state *state = (struct push_state *)priv;
+	int result;
+
+	if (x_feof(state->f)) {
+		return 0;
+	}
+
+	result = readfile(buf, n, state->f);
+	state->nread += result;
+	return result;
+}
+
 /****************************************************************************
  Send a message.
 ****************************************************************************/
@@ -1587,13 +1606,12 @@ static int do_put(const char *rname, const char *lname, bool reput)
 	int fnum;
 	XFILE *f;
 	SMB_OFF_T start = 0;
-	off_t nread = 0;
-	char *buf = NULL;
-	int maxwrite = io_bufsize;
 	int rc = 0;
 	struct timeval tp_start;
 	struct cli_state *targetcli;
 	char *targetname = NULL;
+	struct push_state state;
+	NTSTATUS status;
 
 	if (!cli_resolve_path(ctx, "", cli, rname, &targetcli, &targetname)) {
 		d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
@@ -1646,42 +1664,20 @@ static int do_put(const char *rname, const char *lname, bool reput)
 	DEBUG(1,("putting file %s as %s ",lname,
 		 rname));
 
-	buf = (char *)SMB_MALLOC(maxwrite);
-	if (!buf) {
-		d_printf("ERROR: Not enough memory!\n");
-		return 1;
-	}
+	x_setvbuf(f, NULL, X_IOFBF, io_bufsize);
 
-	x_setvbuf(f, NULL, X_IOFBF, maxwrite);
+	state.f = f;
+	state.nread = 0;
 
-	while (!x_feof(f)) {
-		int n = maxwrite;
-		int ret;
-
-		if ((n = readfile(buf,n,f)) < 1) {
-			if((n == 0) && x_feof(f))
-				break; /* Empty local file. */
-
-			d_printf("Error reading local file: %s\n", strerror(errno));
-			rc = 1;
-			break;
-		}
-
-		ret = cli_write(targetcli, fnum, 0, buf, nread + start, n);
-
-		if (n != ret) {
-			d_printf("Error writing file: %s\n", cli_errstr(cli));
-			rc = 1;
-			break;
-		}
-
-		nread += n;
+	status = cli_push(targetcli, fnum, 0, 0, io_bufsize, push_source,
+			  &state);
+	if (!NT_STATUS_IS_OK(status)) {
+		d_fprintf(stderr, "cli_push returned %s\n", nt_errstr(status));
 	}
 
 	if (!cli_close(targetcli, fnum)) {
 		d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
 		x_fclose(f);
-		SAFE_FREE(buf);
 		return 1;
 	}
 
@@ -1689,8 +1685,6 @@ static int do_put(const char *rname, const char *lname, bool reput)
 		x_fclose(f);
 	}
 
-	SAFE_FREE(buf);
-
 	{
 		struct timeval tp_end;
 		int this_time;
@@ -1700,10 +1694,10 @@ static int do_put(const char *rname, const char *lname, bool reput)
 			(tp_end.tv_sec - tp_start.tv_sec)*1000 +
 			(tp_end.tv_usec - tp_start.tv_usec)/1000;
 		put_total_time_ms += this_time;
-		put_total_size += nread;
+		put_total_size += state.nread;
 
 		DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",
-			 nread / (1.024*this_time + 1.0e-4),
+			 state.nread / (1.024*this_time + 1.0e-4),
 			 put_total_size / (1.024*put_total_time_ms)));
 	}
 
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 5584c22..5e5ce37 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -28,6 +28,7 @@ static const char *sockops="TCP_NODELAY";
 static int nprocs=1;
 static int port_to_use=0;
 int torture_numops=100;
+int torture_blocksize=1024*1024;
 static int procnum; /* records process count number when forking */
 static struct cli_state *current_cli;
 static fstring randomfname;
@@ -4974,6 +4975,81 @@ static bool run_chain1(int dummy)
 	return True;
 }
 
+static size_t null_source(uint8_t *buf, size_t n, void *priv)
+{
+	size_t *to_pull = (size_t *)priv;
+	size_t thistime = *to_pull;
+
+	thistime = MIN(thistime, n);
+	if (thistime == 0) {
+		return 0;
+	}
+
+	memset(buf, 0, thistime);
+	*to_pull -= thistime;
+	return thistime;
+}
+
+static bool run_windows_write(int dummy)
+{
+	struct cli_state *cli1;
+	int fnum;
+	int i;
+	bool ret = false;
+	const char *fname = "\\writetest.txt";
+	double seconds;
+	double kbytes;
+
+	printf("starting windows_write test\n");
+	if (!torture_open_connection(&cli1, 0)) {
+		return False;
+	}
+
+	fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+	if (fnum == -1) {
+		printf("open failed (%s)\n", cli_errstr(cli1));
+		return False;
+	}
+
+	cli_sockopt(cli1, sockops);
+
+	start_timer();
+
+	for (i=0; i<torture_numops; i++) {
+		char c = 0;
+		off_t start = i * torture_blocksize;
+		NTSTATUS status;
+		size_t to_pull = torture_blocksize - 1;
+
+		if (cli_write(cli1, fnum, 0, &c,
+			      start + torture_blocksize - 1, 1) != 1) {
+			printf("cli_write failed: %s\n", cli_errstr(cli1));
+			goto fail;
+		}
+
+		status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
+				  null_source, &to_pull);
+		if (!NT_STATUS_IS_OK(status)) {
+			printf("cli_push returned: %s\n", nt_errstr(status));
+			goto fail;
+		}
+	}
+
+	seconds = end_timer();
+	kbytes = (double)torture_blocksize * torture_numops;
+	kbytes /= 1024;
+
+	printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
+	       (double)seconds, (int)(kbytes/seconds));
+
+	ret = true;
+ fail:
+	cli_close(cli1, fnum);
+	cli_unlink(cli1, fname);
+	torture_close_connection(cli1);
+	return ret;
+}
+
 static bool run_cli_echo(int dummy)
 {
 	struct cli_state *cli;
@@ -5535,6 +5611,7 @@ static struct {
 	{ "EATEST", run_eatest, 0},
 	{ "SESSSETUP_BENCH", run_sesssetup_bench, 0},
 	{ "CHAIN1", run_chain1, 0},
+	{ "WINDOWS-WRITE", run_windows_write, 0},
 	{ "CLI_ECHO", run_cli_echo, 0},
 	{ "LOCAL-SUBSTITUTE", run_local_substitute, 0},
 	{ "LOCAL-GENCACHE", run_local_gencache, 0},
@@ -5693,7 +5770,7 @@ static void usage(void)
 
 	fstrcpy(workgroup, lp_workgroup());
 
-	while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:")) != EOF) {
+	while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
 		switch (opt) {
 		case 'p':
 			port_to_use = atoi(optarg);
@@ -5756,6 +5833,9 @@ static void usage(void)
 			fstrcpy(multishare_conn_fname, optarg);
 			use_multishare_conn = True;
 			break;
+		case 'B':
+			torture_blocksize = atoi(optarg);
+			break;
 		default:
 			printf("Unknown option %c (%d)\n", (char)opt, opt);
 			usage();


-- 
Samba Shared Repository


More information about the samba-cvs mailing list