Exemple #1
0
/* run a test that simulates an approximate netbench client load */
bool torture_nbench(struct torture_context *torture)
{
	bool correct = true;
	int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
	struct smbcli_state *cli;
	const char *p;

	read_only = torture_setting_bool(torture, "readonly", false);

	nb_max_retries = torture_setting_int(torture, "nretries", 1);

	p = torture_setting_string(torture, "timelimit", NULL);
	if (p && *p) {
		timelimit = atoi(p);
	}

	warmup = timelimit / 20;

	loadfile = torture_setting_string(torture, "loadfile", NULL);
	if (!loadfile || !*loadfile) {
		loadfile = "client.txt";
	}

	if (torture_nprocs > 1) {
		if (!torture_open_connection(&cli, torture, 0)) {
			return false;
		}

		if (!read_only && !torture_setup_dir(cli, "\\clients")) {
			return false;
		}
	}

	nbio_shmem(torture_nprocs, timelimit, warmup);

	printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
	       timelimit, loadfile, warmup);

	/* we need to reset SIGCHLD here as the name resolution
	   library may have changed it. We rely on correct signals
	   from childs in the main torture code which reaps
	   children. This is why smbtorture BENCH-NBENCH was sometimes
	   failing */
	signal(SIGCHLD, SIG_DFL);


	signal(SIGALRM, nb_alarm);
	alarm(1);
	torture_create_procs(torture, run_netbench, &correct);
	alarm(0);

	if (!read_only && torture_nprocs > 1) {
		smbcli_deltree(cli->tree, "\\clients");
	}

	printf("\nThroughput %g MB/sec\n", nbio_result());
	return correct;
}
Exemple #2
0
/* Test the rate at which the server will accept connections.  */
bool torture_bench_treeconnect(struct torture_context *tctx)
{
	const char *host = torture_setting_string(tctx, "host", NULL);
	const char *share = torture_setting_string(tctx, "share", NULL);

	int timelimit = torture_setting_int(tctx, "timelimit",
					TIME_LIMIT_SECS);
	int nprocs = torture_setting_int(tctx, "nprocs", 4);

	int *curr_counts = map_count_buffer(nprocs, sizeof(int));
	int *last_counts = talloc_array(NULL, int, nprocs);

	struct timeval now, last, start;
	int i, delta;

	torture_assert(tctx, nprocs > 0, "bad proc count");
	torture_assert(tctx, timelimit > 0, "bad timelimit");
	torture_assert(tctx, curr_counts, "allocation failure");
	torture_assert(tctx, last_counts, "allocation failure");

	start = last = timeval_current();
	for (i = 0; i < nprocs; ++i) {
		fork_tcon_client(tctx, &curr_counts[i], timelimit, host, share);
	}

	while (children_remain()) {

		sleep(1);
		now = timeval_current();

		for (i = 0, delta = 0; i < nprocs; ++i) {
			delta += curr_counts[i] - last_counts[i];
		}

		printf("%u connections/sec\n",
			(unsigned)rate_convert_secs(delta, &last, &now));

		memcpy(last_counts, curr_counts, nprocs * sizeof(int));
		last = timeval_current();
	}

	now = timeval_current();

	for (i = 0, delta = 0; i < nprocs; ++i) {
		delta += curr_counts[i];
	}

	printf("TOTAL: %u connections/sec over %u secs\n",
			(unsigned)rate_convert_secs(delta, &start, &now),
			timelimit);
	return true;
}
Exemple #3
0
static bool test_async_resolve(struct torture_context *tctx)
{
	struct nbt_name n;
	struct tevent_context *ev;
	int timelimit = torture_setting_int(tctx, "timelimit", 2);
	const char *host = torture_setting_string(tctx, "host", NULL);
	int count = 0;
	struct timeval tv = timeval_current();
	TALLOC_CTX *mem_ctx = tctx;

	ev = tctx->ev;

	ZERO_STRUCT(n);
	n.name = host;

	torture_comment(tctx, "Testing async resolve of '%s' for %d seconds\n",
			host, timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		struct socket_address **s;
		struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, 0, 0, &n);
		torture_assert(tctx, c != NULL, "resolve_name_host_send");
		torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s, NULL),
								   "async resolve failed");
		count++;
	}

	torture_comment(tctx, "async rate of %.1f resolves/sec\n", 
			count/timeval_elapsed(&tv));
	return true;
}
Exemple #4
0
bool torture_sec_leak(struct torture_context *tctx, struct smbcli_state *cli)
{
	time_t t1 = time_mono(NULL);
	int timelimit = torture_setting_int(tctx, "timelimit", 20);

	while (time_mono(NULL) < t1+timelimit) {
		if (!try_failed_login(tctx, cli)) {
			return false;
		}
		talloc_report(NULL, stdout);
	}

	return true;
}
Exemple #5
0
/*
  test resolution using sync method
*/
static bool test_sync_resolve(struct torture_context *tctx)
{
	int timelimit = torture_setting_int(tctx, "timelimit", 2);
	struct timeval tv = timeval_current();
	int count = 0;
	const char *host = torture_setting_string(tctx, "host", NULL);

	torture_comment(tctx, "Testing sync resolve of '%s' for %d seconds\n", 
			host, timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		inet_ntoa(interpret_addr2(host));
		count++;
	}
	
	torture_comment(tctx, "sync rate of %.1f resolves/sec\n", 
			count/timeval_elapsed(&tv));
	return true;
}
Exemple #6
0
static bool torture_winbind_struct_ping(struct torture_context *torture)
{
	struct timeval tv = timeval_current();
	int timelimit = torture_setting_int(torture, "timelimit", 5);
	uint32_t total = 0;

	torture_comment(torture,
			"Running WINBINDD_PING (struct based) for %d seconds\n",
			timelimit);

	while (timeval_elapsed(&tv) < timelimit) {
		DO_STRUCT_REQ_REP(WINBINDD_PING, NULL, NULL);
		total++;
	}

	torture_comment(torture,
			"%u (%.1f/s) WINBINDD_PING (struct based)\n",
			total, total / timeval_elapsed(&tv));

	return true;
}
Exemple #7
0
/*
 * Test for maximum ea size - more than one ea name is checked.
 *
 * Additional parameters can be passed, to allow further testing:
 *
 *             default
 * maxeasize    65536   limit the max. size for a single EA name
 * maxeanames     101   limit of the number of tested names
 * maxeastart       1   this EA size is used to test for the 1st EA (atm)
 * maxeadebug       0   if set true, further debug output is done - in addition
 *                      the testfile is not deleted for further inspection!
 *
 * Set some/all of these options on the cmdline with:
 * --option torture:maxeasize=1024 --option torture:maxeadebug=1 ...
 *
 */
static bool test_max_eas(struct smbcli_state *cli, struct torture_context *tctx)
{
	NTSTATUS status;
	union smb_open io;
	const char *fname = BASEDIR "\\ea_max.txt";
	int fnum = -1;
	bool ret = true;
	bool err = false;

	int       i, j, k, last, total;
	DATA_BLOB eablob;
	char      *eaname = NULL;
	int       maxeasize;
	int       maxeanames;
	int       maxeastart;

	torture_comment(tctx, "TESTING SETFILEINFO MAX. EA_SET\n");

	maxeasize  = torture_setting_int(tctx, "maxeasize", 65536);
	maxeanames = torture_setting_int(tctx, "maxeanames", 101);
	maxeastart = torture_setting_int(tctx, "maxeastart", 1);
	maxeadebug = torture_setting_int(tctx, "maxeadebug", 0);

	/* Do some sanity check on possibly passed parms */
	if (maxeasize <= 0) {
		torture_comment(tctx, "Invalid parameter 'maxeasize=%d'",maxeasize);
		err = true;
	}
	if (maxeanames <= 0) {
		torture_comment(tctx, "Invalid parameter 'maxeanames=%d'",maxeanames);
		err = true;
	}
	if (maxeastart <= 0) {
		torture_comment(tctx, "Invalid parameter 'maxeastart=%d'",maxeastart);
		err = true;
	}
	if (maxeadebug < 0) {
		torture_comment(tctx, "Invalid parameter 'maxeadebug=%d'",maxeadebug);
		err = true;
	}
	if (err) {
	  torture_comment(tctx, "\n\n");
	  goto done;
	}
	if (maxeastart > maxeasize) {
		maxeastart = maxeasize;
		torture_comment(tctx, "'maxeastart' outside range - corrected to %d\n",
			maxeastart);
	}
	torture_comment(tctx, "MAXEA parms: maxeasize=%d maxeanames=%d maxeastart=%d"
	       " maxeadebug=%d\n", maxeasize, maxeanames, maxeastart,
	       maxeadebug);

	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid.fnum = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access =
		NTCREATEX_SHARE_ACCESS_READ |
		NTCREATEX_SHARE_ACCESS_WRITE;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, tctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	eablob = data_blob_talloc(tctx, NULL, maxeasize);
	if (eablob.data == NULL) {
		goto done;
	}
	/*
	 * Fill in some EA data - the offset could be easily checked
	 * during a hexdump.
	 */
	for (i = 0, k = 0; i < eablob.length / 4; i++, k+=4) {
		eablob.data[k]   = k & 0xff;
		eablob.data[k+1] = (k >>  8) & 0xff;
		eablob.data[k+2] = (k >> 16) & 0xff;
		eablob.data[k+3] = (k >> 24) & 0xff;
	}

	i = eablob.length % 4;
	if (i-- > 0) {
		eablob.data[k] = k & 0xff;
		if (i-- > 0) {
			eablob.data[k+1] = (k >>  8) & 0xff;
			if (i-- > 0) {
				eablob.data[k+2] = (k >> 16) & 0xff;
			}
Exemple #8
0
/* 
   test offline file handling
*/
bool torture_test_offline(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct offline_state *state;
	struct smbcli_state *cli;
	bool progress;
	progress = torture_setting_bool(torture, "progress", true);

	nconnections = torture_setting_int(torture, "nprocs", 4);
	numstates = nconnections * torture_entries;

	state = talloc_zero_array(mem_ctx, struct offline_state, numstates);

	printf("Opening %d connections with %d simultaneous operations and %u files\n", nconnections, numstates, torture_numops);
	for (i=0;i<nconnections;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&cli, i, torture, torture->ev)) {
			return false;
		}
		state[i].tree = cli->tree;
		state[i].client = i;
		/* allow more time for offline files */
		state[i].tree->session->transport->options.request_timeout = 200;
	}

	/* the others are repeats on the earlier connections */
	for (i=nconnections;i<numstates;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		state[i].tree = state[i % nconnections].tree;
		state[i].client = i;
	}

	num_connected = i;

	if (!torture_setup_dir(cli, BASEDIR)) {
		goto failed;
	}

	/* pre-create files */
	printf("Pre-creating %u files ....\n", torture_numops);
	for (i=0;i<torture_numops;i++) {
		int fnum;
		char *fname = filename(mem_ctx, i);
		char buf[FILE_SIZE];
		NTSTATUS status;

		memset(buf, 1+(i % 255), sizeof(buf));

		fnum = smbcli_open(state[0].tree, fname, O_RDWR|O_CREAT, DENY_NONE);
		if (fnum == -1) {
			printf("Failed to open %s on connection %d\n", fname, i);
			goto failed;
		}

		if (smbcli_write(state[0].tree, fnum, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
			printf("Failed to write file of size %u\n", FILE_SIZE);
			goto failed;
		}

		status = smbcli_close(state[0].tree, fnum);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Close failed - %s\n", nt_errstr(status));
			goto failed;
		}

		talloc_free(fname);
	}

	/* start the async ops */
	for (i=0;i<numstates;i++) {
		state[i].tv_start = timeval_current();
		test_offline(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (test_failed) {
			DEBUG(0,("test failed\n"));
			goto failed;
		}
	}

	printf("\nWaiting for completion\n");
	test_finished = true;
	for (i=0;i<numstates;i++) {
		while (state[i].loadfile || 
		       state[i].savefile ||
		       state[i].req) {
			event_loop_once(torture->ev);
		}
	}	

	printf("worst latencies: set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\n",
	       worst_latencies[OP_SETOFFLINE],
	       worst_latencies[OP_GETOFFLINE],
	       worst_latencies[OP_SAVEFILE],
	       worst_latencies[OP_LOADFILE]);

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	printf("\n");
	return ret;

failed:
	talloc_free(mem_ctx);
	return false;
}
Exemple #9
0
/*
  test tdb speed
*/
static bool test_tdb_speed(struct torture_context *torture, const void *_data)
{
	struct timeval tv;
	struct tdb_wrap *tdbw;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	int i, count;
	TALLOC_CTX *tmp_ctx = talloc_new(torture);

	unlink("test.tdb");

	torture_comment(torture, "Testing tdb speed for sidmap\n");

	tdbw = tdb_wrap_open(tmp_ctx, "test.tdb", 
			     10000, 0, O_RDWR|O_CREAT|O_TRUNC, 0600);
	if (!tdbw) {
		unlink("test.tdb");
		talloc_free(tmp_ctx);
		torture_fail(torture, "Failed to open test.tdb");
	}

	torture_comment(torture, "Adding %d SID records\n", torture_entries);

	for (i=0;i<torture_entries;i++) {
		if (!tdb_add_record(tdbw, 
				    "S-1-5-21-53173311-3623041448-2049097239-%u",
				    "UID %u", i)) {
			torture_result(torture, TORTURE_FAIL, "Failed to add SID %d\n", i);
			goto failed;
		}
		if (!tdb_add_record(tdbw, 
				    "UID %u",
				    "S-1-5-21-53173311-3623041448-2049097239-%u", i)) {
			torture_result(torture, TORTURE_FAIL, "Failed to add UID %d\n", i);
			goto failed;
		}
	}

	torture_comment(torture, "Testing for %d seconds\n", timelimit);

	tv = timeval_current();

	for (count=0;timeval_elapsed(&tv) < timelimit;count++) {
		TDB_DATA key, data;
		i = random() % torture_entries;
		key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "S-1-5-21-53173311-3623041448-2049097239-%u", i);
		key.dsize = strlen((char *)key.dptr)+1;
		data = tdb_fetch(tdbw->tdb, key);
		talloc_free(key.dptr);
		if (data.dptr == NULL) {
			torture_result(torture, TORTURE_FAIL, "Failed to fetch SID %d\n", i);
			goto failed;
		}
		free(data.dptr);
		key.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "UID %u", i);
		key.dsize = strlen((char *)key.dptr)+1;
		data = tdb_fetch(tdbw->tdb, key);
		talloc_free(key.dptr);
		if (data.dptr == NULL) {
			torture_result(torture, TORTURE_FAIL, "Failed to fetch UID %d\n", i);
			goto failed;
		}
		free(data.dptr);
	}

	tdb_speed = count/timeval_elapsed(&tv);
	torture_comment(torture, "tdb speed %.2f ops/sec\n", tdb_speed);
	

	unlink("test.tdb");
	talloc_free(tmp_ctx);
	return true;

failed:
	unlink("test.tdb");
	talloc_free(tmp_ctx);
	return false;
}
Exemple #10
0
/*
  test ldb speed
*/
static bool test_ldb_speed(struct torture_context *torture, const void *_data)
{
	struct timeval tv;
	struct ldb_context *ldb;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	int i, count;
	TALLOC_CTX *tmp_ctx = talloc_new(torture);
	struct ldb_ldif *ldif;
	const char *init_ldif = "dn: @INDEXLIST\n" \
		"@IDXATTR: UID\n";
	float ldb_speed;

	unlink("./test.ldb");

	torture_comment(torture, "Testing ldb speed for sidmap\n");

	ldb = ldb_wrap_connect(tmp_ctx, torture->ev, torture->lp_ctx, "tdb://test.ldb", 
				NULL, NULL, LDB_FLG_NOSYNC, NULL);
	if (!ldb) {
		unlink("./test.ldb");
		talloc_free(tmp_ctx);
		torture_fail(torture, "Failed to open test.ldb");
	}

	/* add an index */
	ldif = ldb_ldif_read_string(ldb, &init_ldif);
	if (ldif == NULL) goto failed;
	if (ldb_add(ldb, ldif->msg) != LDB_SUCCESS) goto failed;
	talloc_free(ldif);

	torture_comment(torture, "Adding %d SID records\n", torture_entries);

	for (i=0;i<torture_entries;i++) {
		if (!ldb_add_record(ldb, i)) {
			torture_result(torture, TORTURE_FAIL, "Failed to add SID %d\n", i);
			goto failed;
		}
	}

	if (talloc_total_blocks(torture) > 100) {
		torture_result(torture, TORTURE_FAIL, "memory leak in ldb add\n");
		goto failed;
	}

	torture_comment(torture, "Testing for %d seconds\n", timelimit);

	tv = timeval_current();

	for (count=0;timeval_elapsed(&tv) < timelimit;count++) {
		struct ldb_dn *dn;
		struct ldb_result *res;

		i = random() % torture_entries;
		dn = ldb_dn_new_fmt(tmp_ctx, ldb, "SID=S-1-5-21-53173311-3623041448-2049097239-%u", i);
		if (ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL) != LDB_SUCCESS || res->count != 1) {
			torture_fail(torture, talloc_asprintf(torture, "Failed to find SID %d", i));
		}
		talloc_free(res);
		talloc_free(dn);
		if (ldb_search(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, NULL, "(UID=%u)", i) != LDB_SUCCESS || res->count != 1) {
			torture_fail(torture, talloc_asprintf(torture, "Failed to find UID %d", i));
		}
		talloc_free(res);
	}

	if (talloc_total_blocks(torture) > 100) {
		unlink("./test.ldb");
		talloc_free(tmp_ctx);
		torture_fail(torture, "memory leak in ldb search");
	}

	ldb_speed = count/timeval_elapsed(&tv);
	torture_comment(torture, "ldb speed %.2f ops/sec\n", ldb_speed);

	torture_comment(torture, "ldb/tdb speed ratio is %.2f%%\n", (100*ldb_speed/tdb_speed));
	

	unlink("./test.ldb");
	talloc_free(tmp_ctx);
	return true;

failed:
	unlink("./test.ldb");
	talloc_free(tmp_ctx);
	return false;
}
Exemple #11
0
/*
  test ping speed
*/
static bool test_ping_speed(struct torture_context *tctx)
{
	struct tevent_context *ev;
	struct messaging_context *msg_client_ctx;
	struct messaging_context *msg_server_ctx;
	int ping_count = 0;
	int pong_count = 0;
	struct timeval tv;
	int timelimit = torture_setting_int(tctx, "timelimit", 10);
	uint32_t msg_ping, msg_exit;

	lp_set_cmdline(tctx->lp_ctx, "pid directory", "piddir.tmp");

	ev = tctx->ev;

	msg_server_ctx = messaging_init(tctx, 
					lp_messaging_path(tctx, tctx->lp_ctx), 
					cluster_id(0, 1), 
				        lp_iconv_convenience(tctx->lp_ctx),
					ev);
	
	torture_assert(tctx, msg_server_ctx != NULL, "Failed to init ping messaging context");
		
	messaging_register_tmp(msg_server_ctx, NULL, ping_message, &msg_ping);
	messaging_register_tmp(msg_server_ctx, tctx, exit_message, &msg_exit);

	msg_client_ctx = messaging_init(tctx, 
					lp_messaging_path(tctx, tctx->lp_ctx), 
					cluster_id(0, 2), 
				        lp_iconv_convenience(tctx->lp_ctx),
					ev);

	torture_assert(tctx, msg_client_ctx != NULL, 
		       "msg_client_ctx messaging_init() failed");

	messaging_register_tmp(msg_client_ctx, &pong_count, pong_message, &msg_pong);

	tv = timeval_current();

	torture_comment(tctx, "Sending pings for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		DATA_BLOB data;
		NTSTATUS status1, status2;

		data.data = discard_const_p(uint8_t, "testing");
		data.length = strlen((const char *)data.data);

		status1 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, &data);
		status2 = messaging_send(msg_client_ctx, cluster_id(0, 1), msg_ping, NULL);

		torture_assert_ntstatus_ok(tctx, status1, "msg1 failed");
		ping_count++;

		torture_assert_ntstatus_ok(tctx, status2, "msg2 failed");
		ping_count++;

		while (ping_count > pong_count + 20) {
			event_loop_once(ev);
		}
	}

	torture_comment(tctx, "waiting for %d remaining replies (done %d)\n", 
	       ping_count - pong_count, pong_count);
	while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
		event_loop_once(ev);
	}

	torture_comment(tctx, "sending exit\n");
	messaging_send(msg_client_ctx, cluster_id(0, 1), msg_exit, NULL);

	torture_assert_int_equal(tctx, ping_count, pong_count, "ping test failed");

	torture_comment(tctx, "ping rate of %.0f messages/sec\n", 
	       (ping_count+pong_count)/timeval_elapsed(&tv));

	talloc_free(msg_client_ctx);
	talloc_free(msg_server_ctx);

	return true;
}
Exemple #12
0
/* 
   ping pong
*/
bool torture_ping_pong(struct torture_context *torture)
{
	const char *fn;
	int num_locks;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	static bool do_reads;
	static bool do_writes;
	int lock_timeout;
	int fd;
	struct smbcli_state *cli;
	int i;
	uint8_t incr=0, last_incr=0;
	uint8_t *val;
	int count, loops;
	struct timeval start;

	fn = torture_setting_string(torture, "filename", NULL);
	if (fn == NULL) {
		DEBUG(0,("You must specify the filename using --option=torture:filename=...\n"));
		return false;
	}

	num_locks = torture_setting_int(torture, "num_locks", -1);
	if (num_locks == -1) {
		DEBUG(0,("You must specify num_locks using --option=torture:num_locks=...\n"));
		return false;
	}

	do_reads     = torture_setting_bool(torture, "read", false);
	do_writes    = torture_setting_bool(torture, "write", false);
	lock_timeout =  torture_setting_int(torture, "lock_timeout", 100000);

	if (!torture_open_connection(&cli, torture, 0)) {
		DEBUG(0,("Could not open connection\n"));
		return false;
	}

	fd = smbcli_open(cli->tree, fn, O_RDWR|O_CREAT, DENY_NONE);
	if (fd == -1) {
		printf("Failed to open %s\n", fn);
		exit(1);
	}

	write_byte(cli, fd, 0, num_locks);
	lock_byte(cli, fd, 0, lock_timeout);


	start = timeval_current();
	val = talloc_zero_array(mem_ctx, uint8_t, num_locks);
	i = 0;
	count = 0;
	loops = 0;
	while (1) {
		lock_byte(cli, fd, (i+1)%num_locks, lock_timeout);

		if (do_reads) {
			uint8_t c;
			read_byte(cli, fd, &c, i);
			incr   = c-val[i];
			val[i] = c;			
		}

		if (do_writes) {
			uint8_t c = val[i] + 1;
			write_byte(cli, fd, c, i);
		}

		unlock_byte(cli, fd, i);

		i = (i+1)%num_locks;
		count++;
		if (loops>num_locks && incr!=last_incr) {
			last_incr = incr;
			printf("data increment = %u\n", incr);
			fflush(stdout);
		}
		if (timeval_elapsed(&start) > 1.0) {
			printf("%8u locks/sec\r", 
			       (unsigned)(2*count/timeval_elapsed(&start)));
			fflush(stdout);
			start = timeval_current();
			count=0;
		}
		loops++;
	}
}
Exemple #13
0
/* 
   benchmark open calls
*/
bool torture_bench_open(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct benchopen_state *state;
	int total = 0;
	int total_retries = 0;
	int minops = 0;
	bool progress=false;

	progress = torture_setting_bool(torture, "progress", true);
	
	nprocs = torture_setting_int(torture, "nprocs", 4);

	state = talloc_zero_array(mem_ctx, struct benchopen_state, nprocs);

	printf("Opening %d connections\n", nprocs);
	for (i=0;i<nprocs;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].client_num = i;
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&state[i].cli, i, torture, torture->ev)) {
			return false;
		}
		talloc_steal(mem_ctx, state);
		state[i].tree = state[i].cli->tree;
		state[i].dest_host = talloc_strdup(state[i].mem_ctx, 
						   state[i].cli->tree->session->transport->socket->hostname);
		state[i].dest_ports = talloc_array(state[i].mem_ctx, 
						   const char *, 2);
		state[i].dest_ports[0] = talloc_asprintf(state[i].dest_ports, 
							 "%u", state[i].cli->tree->session->transport->socket->port);
		state[i].dest_ports[1] = NULL;
		state[i].called_name  = talloc_strdup(state[i].mem_ctx,
						      state[i].cli->tree->session->transport->called.name);
		state[i].service_type = talloc_strdup(state[i].mem_ctx,
						      state[i].cli->tree->device);
	}

	num_connected = i;

	if (!torture_setup_dir(state[0].cli, BASEDIR)) {
		goto failed;
	}

	fnames = talloc_array(mem_ctx, char *, 3*nprocs);
	for (i=0;i<3*nprocs;i++) {
		fnames[i] = talloc_asprintf(fnames, "%s\\file%d.dat", BASEDIR, i);
	}

	for (i=0;i<nprocs;i++) {
		/* all connections start with the same file */
		state[i].next_file_num = 0;
		state[i].open_fnum = -1;
		state[i].close_fnum = -1;
		next_open(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		report_te = event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), 
					    report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (open_failed) {
			DEBUG(0,("open failed\n"));
			goto failed;
		}
		if (close_failed) {
			DEBUG(0,("open failed\n"));
			goto failed;
		}
	}

	talloc_free(report_te);
	if (progress) {
		for (i=0;i<nprocs;i++) {
			printf("      ");
		}
		printf("\r");
	}

	minops = state[0].count;
	for (i=0;i<nprocs;i++) {
		total += state[i].count;
		total_retries += state[i].open_retries;
		printf("[%d] %u ops (%u retries)\n",
		       i, state[i].count, state[i].open_retries);
		if (state[i].count < minops) minops = state[i].count;
	}
	printf("%.2f ops/second (%d retries)\n",
	       total/timeval_elapsed(&tv), total_retries);
	if (minops < 0.5*total/nprocs) {
		printf("Failed: unbalanced open\n");
		goto failed;
	}

	for (i=0;i<nprocs;i++) {
		talloc_free(state[i].req_open);
		talloc_free(state[i].req_close);
		smb_raw_exit(state[i].tree->session);
	}

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	return ret;

failed:
	talloc_free(mem_ctx);
	return false;
}
Exemple #14
0
/*
  test writing
*/
static NTSTATUS torture_smb2_write(struct torture_context *tctx, struct smb2_tree *tree, struct smb2_handle handle)
{
	struct smb2_write w;
	struct smb2_read r;
	struct smb2_flush f;
	NTSTATUS status;
	DATA_BLOB data;
	int i;
	
	if (torture_setting_bool(tctx, "dangerous", false)) {
		data = data_blob_talloc(tree, NULL, 160000);
	} else if (torture_setting_bool(tctx, "samba4", false)) {
		data = data_blob_talloc(tree, NULL, UINT16_MAX);
	} else {
		data = data_blob_talloc(tree, NULL, torture_setting_int(tctx, "smb2maxwrite", 120000));
	}
	for (i=0;i<data.length;i++) {
		data.data[i] = i;
	}

	ZERO_STRUCT(w);
	w.in.file.handle = handle;
	w.in.offset      = 0;
	w.in.data        = data;

	status = smb2_write(tree, &w);
	if (!NT_STATUS_IS_OK(status)) {
		printf("write failed - %s\n", nt_errstr(status));
		return status;
	}

	torture_smb2_all_info(tree, handle);

	status = smb2_write(tree, &w);
	if (!NT_STATUS_IS_OK(status)) {
		printf("write failed - %s\n", nt_errstr(status));
		return status;
	}

	torture_smb2_all_info(tree, handle);

	ZERO_STRUCT(f);
	f.in.file.handle = handle;

	status = smb2_flush(tree, &f);
	if (!NT_STATUS_IS_OK(status)) {
		printf("flush failed - %s\n", nt_errstr(status));
		return status;
	}

	ZERO_STRUCT(r);
	r.in.file.handle = handle;
	r.in.length      = data.length;
	r.in.offset      = 0;

	status = smb2_read(tree, tree, &r);
	if (!NT_STATUS_IS_OK(status)) {
		printf("read failed - %s\n", nt_errstr(status));
		return status;
	}

	if (data.length != r.out.data.length ||
	    memcmp(data.data, r.out.data.data, data.length) != 0) {
		printf("read data mismatch\n");
		return NT_STATUS_NET_WRITE_FAULT;
	}

	return status;
}
Exemple #15
0
/* 
   benchmark locking calls
*/
bool torture_bench_lock(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i, j;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct benchlock_state *state;
	int total = 0, minops=0;
	struct smbcli_state *cli;
	bool progress;
	off_t offset;
	int initial_locks = torture_setting_int(torture, "initial_locks", 0);

	progress = torture_setting_bool(torture, "progress", true);

	nprocs = torture_setting_int(torture, "nprocs", 4);

	state = talloc_zero_array(mem_ctx, struct benchlock_state, nprocs);

	printf("Opening %d connections\n", nprocs);
	for (i=0;i<nprocs;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].client_num = i;
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&cli, i, torture, torture->ev)) {
			return false;
		}
		talloc_steal(mem_ctx, state);
		state[i].tree = cli->tree;
		state[i].dest_host = talloc_strdup(state[i].mem_ctx, 
						   cli->tree->session->transport->socket->hostname);
		state[i].dest_ports = talloc_array(state[i].mem_ctx, 
						   const char *, 2);
		state[i].dest_ports[0] = talloc_asprintf(state[i].dest_ports, 
							 "%u", 
							 cli->tree->session->transport->socket->port);
		state[i].dest_ports[1] = NULL;
		state[i].called_name  = talloc_strdup(state[i].mem_ctx,
						      cli->tree->session->transport->called.name);
		state[i].service_type = talloc_strdup(state[i].mem_ctx,
						      cli->tree->device);
	}

	num_connected = i;

	if (!torture_setup_dir(cli, BASEDIR)) {
		goto failed;
	}

	for (i=0;i<nprocs;i++) {
		state[i].fnum = smbcli_open(state[i].tree, 
					    FNAME, 
					    O_RDWR|O_CREAT, DENY_NONE);
		if (state[i].fnum == -1) {
			printf("Failed to open %s on connection %d\n", FNAME, i);
			goto failed;
		}

		/* Optionally, lock initial_locks for each proc beforehand. */
		if (i == 0 && initial_locks > 0) {
			printf("Initializing %d locks on each proc.\n",
			    initial_locks);
		}

		for (j = 0; j < initial_locks; j++) {
			offset = (0xFFFFFED8LLU * (i+2)) + j;
			if (!NT_STATUS_IS_OK(smbcli_lock64(state[i].tree,
			    state[i].fnum, offset, 1, 0, WRITE_LOCK))) {
				printf("Failed initializing, lock=%d\n", j);
				goto failed;
			}
		}

		state[i].stage = LOCK_INITIAL;
		lock_send(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (lock_failed) {
			DEBUG(0,("locking failed\n"));
			goto failed;
		}
	}

	printf("%.2f ops/second\n", total/timeval_elapsed(&tv));
	minops = state[0].count;
	for (i=0;i<nprocs;i++) {
		printf("[%d] %u ops\n", i, state[i].count);
		if (state[i].count < minops) minops = state[i].count;
	}
	if (minops < 0.5*total/nprocs) {
		printf("Failed: unbalanced locking\n");
		goto failed;
	}

	for (i=0;i<nprocs;i++) {
		talloc_free(state[i].req);
		smb_raw_exit(state[i].tree->session);
	}

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	printf("\n");
	return ret;

failed:
	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	return false;
}
Exemple #16
0
/* run a test that simulates an approximate netbench client load */
static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli, int client)
{
	int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
	int i;
	char line[1024];
	char *cname;
	FILE *f;
	bool correct = true;
	double target_rate = torture_setting_double(tctx, "targetrate", 0);	
	int n;

	if (target_rate != 0 && client == 0) {
		printf("Targetting %.4f MByte/sec\n", target_rate);
	}

	nb_setup(cli, client);

	if (torture_nprocs == 1) {
		if (!read_only) {
			NB_RETRY(torture_setup_dir(cli, "\\clients"));
		}
	}

	asprintf(&cname, "client%d", client+1);

	f = fopen(loadfile, "r");

	if (!f) {
		perror(loadfile);
		return false;
	}

again:
	nbio_time_reset();

	while (fgets(line, sizeof(line)-1, f)) {
		NTSTATUS status;
		const char **params0, **params;

		nbench_line_count++;

		line[strlen(line)-1] = 0;

		all_string_sub(line,"client1", cname, sizeof(line));
		
		params = params0 = str_list_make_shell(NULL, line, " ");
		i = str_list_length(params);

		if (i > 0 && isdigit(params[0][0])) {
			double targett = strtod(params[0], NULL);
			if (target_rate != 0) {
				nbio_target_rate(target_rate);
			} else {
				nbio_time_delay(targett);
			}
			params++;
			i--;
		} else if (target_rate != 0) {
			nbio_target_rate(target_rate);
		}

		if (i < 2 || params[0][0] == '#') continue;

		if (!strncmp(params[0],"SMB", 3)) {
			printf("ERROR: You are using a dbench 1 load file\n");
			nb_exit(1);
		}

		if (strncmp(params[i-1], "NT_STATUS_", 10) != 0 &&
		    strncmp(params[i-1], "0x", 2) != 0) {
			printf("Badly formed status at line %d\n", nbench_line_count);
			talloc_free(params);
			continue;
		}

		/* accept numeric or string status codes */
		if (strncmp(params[i-1], "0x", 2) == 0) {
			status = NT_STATUS(strtoul(params[i-1], NULL, 16));
		} else {
			status = nt_status_string_to_code(params[i-1]);
		}

		DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));

		if (!strcmp(params[0],"NTCreateX")) {
			NB_RETRY(nb_createx(params[1], ival(params[2]), ival(params[3]), 
					    ival(params[4]), status));
		} else if (!strcmp(params[0],"Close")) {
			NB_RETRY(nb_close(ival(params[1]), status));
		} else if (!read_only && !strcmp(params[0],"Rename")) {
			NB_RETRY(nb_rename(params[1], params[2], status, n>0));
		} else if (!read_only && !strcmp(params[0],"Unlink")) {
			NB_RETRY(nb_unlink(params[1], ival(params[2]), status, n>0));
		} else if (!read_only && !strcmp(params[0],"Deltree")) {
			NB_RETRY(nb_deltree(params[1], n>0));
		} else if (!read_only && !strcmp(params[0],"Rmdir")) {
			NB_RETRY(nb_rmdir(params[1], status, n>0));
		} else if (!read_only && !strcmp(params[0],"Mkdir")) {
			NB_RETRY(nb_mkdir(params[1], status, n>0));
		} else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
			NB_RETRY(nb_qpathinfo(params[1], ival(params[2]), status));
		} else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
			NB_RETRY(nb_qfileinfo(ival(params[1]), ival(params[2]), status));
		} else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
			NB_RETRY(nb_qfsinfo(ival(params[1]), status));
		} else if (!read_only && !strcmp(params[0],"SET_FILE_INFORMATION")) {
			NB_RETRY(nb_sfileinfo(ival(params[1]), ival(params[2]), status));
		} else if (!strcmp(params[0],"FIND_FIRST")) {
			NB_RETRY(nb_findfirst(params[1], ival(params[2]), 
					      ival(params[3]), ival(params[4]), status));
		} else if (!read_only && !strcmp(params[0],"WriteX")) {
			NB_RETRY(nb_writex(ival(params[1]), 
					   ival(params[2]), ival(params[3]), ival(params[4]),
					   status));
		} else if (!read_only && !strcmp(params[0],"Write")) {
			NB_RETRY(nb_write(ival(params[1]), 
					  ival(params[2]), ival(params[3]), ival(params[4]),
					  status));
		} else if (!strcmp(params[0],"LockX")) {
			NB_RETRY(nb_lockx(ival(params[1]), 
					  ival(params[2]), ival(params[3]), status));
		} else if (!strcmp(params[0],"UnlockX")) {
			NB_RETRY(nb_unlockx(ival(params[1]), 
					    ival(params[2]), ival(params[3]), status));
		} else if (!strcmp(params[0],"ReadX")) {
			NB_RETRY(nb_readx(ival(params[1]), 
					  ival(params[2]), ival(params[3]), ival(params[4]),
					  status));
		} else if (!strcmp(params[0],"Flush")) {
			NB_RETRY(nb_flush(ival(params[1]), status));
		} else if (!strcmp(params[0],"Sleep")) {
			nb_sleep(ival(params[1]), status);
		} else {
			printf("[%d] Unknown operation %s\n", nbench_line_count, params[0]);
		}

		if (n > nb_max_retries) {
			printf("Maximum reconnect retries reached for op '%s'\n", params[0]);
			nb_exit(1);
		}

		talloc_free(params0);
		
		if (nb_tick()) goto done;
	}

	rewind(f);
	goto again;

done:
	fclose(f);

	if (!read_only && torture_nprocs == 1) {
		smbcli_deltree(cli->tree, "\\clients");
	}
	if (!torture_close_connection(cli)) {
		correct = false;
	}
	
	return correct;
}