Exemplo n.º 1
0
/*
  test disconnect with timed lock
*/
static bool test_disconnect_lock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_lock io;
	NTSTATUS status;
	int fnum;
	struct smbcli_request *req;
	struct smb_lock_entry lock[1];

	printf("trying disconnect with async lock\n");

	fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", 
			   O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("open failed in mux_write - %s\n", smbcli_errstr(cli->tree));
		return false;
	}

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.file.fnum = fnum;
	io.lockx.in.mode = 0;
	io.lockx.in.timeout = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.ulock_cnt = 0;
	lock[0].pid = 1;
	lock[0].offset = 0;
	lock[0].count = 4;
	io.lockx.in.locks = &lock[0];

	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	lock[0].pid = 2;
	io.lockx.in.timeout = 3000;
	req = smb_raw_lock_send(cli->tree, &io);
	if (!req) {
		printf("test_disconnect_lock: smb_raw_lock_send() "
			"returned NULL\n");
		return false;
	}

	status = smbcli_chkpath(cli->tree, "\\");
	CHECK_STATUS(status, NT_STATUS_OK);

	talloc_free(cli);

	return true;
}
Exemplo n.º 2
0
/*
  send the next lock request
*/
static void lock_send(struct benchlock_state *state)
{
	union smb_lock io;
	struct smb_lock_entry lock;

	switch (state->stage) {
	case LOCK_INITIAL:
		io.lockx.in.ulock_cnt = 0;
		io.lockx.in.lock_cnt = 1;
		state->lock_offset = 0;
		state->unlock_offset = 0;
		lock.offset = state->lock_offset;
		break;
	case LOCK_LOCK:
		io.lockx.in.ulock_cnt = 0;
		io.lockx.in.lock_cnt = 1;
		state->lock_offset = (state->lock_offset+1)%(nprocs+1);
		lock.offset = state->lock_offset;
		break;
	case LOCK_UNLOCK:
		io.lockx.in.ulock_cnt = 1;
		io.lockx.in.lock_cnt = 0;
		lock.offset = state->unlock_offset;
		state->unlock_offset = (state->unlock_offset+1)%(nprocs+1);
		break;
	}

	lock.count = 1;
	lock.pid = state->tree->session->pid;

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
	io.lockx.in.timeout = 100000;
	io.lockx.in.locks = &lock;
	io.lockx.in.file.fnum = state->fnum;

	state->req = smb_raw_lock_send(state->tree, &io);
	if (state->req == NULL) {
		DEBUG(0,("Failed to setup lock\n"));
		lock_failed++;
	}
	state->req->async.private_data = state;
	state->req->async.fn      = lock_completion;
}
Exemplo n.º 3
0
/*
  lock a byte range
*/
static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, 
			  struct ntvfs_request *req, union smb_lock *io)
{
	struct cvfs_private *p = ntvfs->private_data;
	struct smbcli_request *c_req;

	SETUP_PID;

	if (io->generic.level != RAW_LOCK_GENERIC &&
	    p->map_generic) {
		return ntvfs_map_lock(ntvfs, req, io);
	}
	SETUP_FILE;

	if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
		return smb_raw_lock(p->tree, io);
	}

	c_req = smb_raw_lock_send(p->tree, io);
	SIMPLE_ASYNC_TAIL;
}
Exemplo n.º 4
0
/*
  test a lock that conflicts with an existing lock
*/
static bool test_mux_lock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_lock io;
	NTSTATUS status;
	int fnum;
	bool ret = true;
	struct smbcli_request *req;
	struct smb_lock_entry lock[1];
	struct timeval t;

	printf("TESTING MULTIPLEXED LOCK/LOCK/UNLOCK\n");

	fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("open failed in mux_write - %s\n", smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	printf("establishing a lock\n");
	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.file.fnum = fnum;
	io.lockx.in.mode = 0;
	io.lockx.in.timeout = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.ulock_cnt = 0;
	lock[0].pid = 1;
	lock[0].offset = 0;
	lock[0].count = 4;
	io.lockx.in.locks = &lock[0];

	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the second lock will conflict with the first\n");
	lock[0].pid = 2;
	io.lockx.in.timeout = 1000;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	printf("this will too, but we'll unlock while waiting\n");
	t = timeval_current();
	req = smb_raw_lock_send(cli->tree, &io);

	printf("unlock the first range\n");
	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 1;
	io.lockx.in.lock_cnt = 0;
	io.lockx.in.timeout = 0;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("recv the async reply\n");
	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_OK);	

	printf("async lock took %.2f msec\n", timeval_elapsed(&t) * 1000);
	if (timeval_elapsed(&t) > 0.1) {
		printf("failed to trigger early lock retry\n");
		return false;		
	}

	printf("reopening with an exit\n");
	smb_raw_exit(cli->session);
	fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", O_RDWR | O_CREAT, DENY_NONE);

	printf("Now trying with a cancel\n");

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.file.fnum = fnum;
	io.lockx.in.mode = 0;
	io.lockx.in.timeout = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.ulock_cnt = 0;
	lock[0].pid = 1;
	lock[0].offset = 0;
	lock[0].count = 4;
	io.lockx.in.locks = &lock[0];

	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	lock[0].pid = 2;
	io.lockx.in.timeout = 1000;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	req = smb_raw_lock_send(cli->tree, &io);

	/* cancel the blocking lock */
	smb_raw_ntcancel(req);

	printf("sending 2nd cancel\n");
	/* the 2nd cancel is totally harmless, but tests the server trying to 
	   cancel an already cancelled request */
	smb_raw_ntcancel(req);

	printf("sent 2nd cancel\n");

	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 1;
	io.lockx.in.lock_cnt = 0;
	io.lockx.in.timeout = 0;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);	

	printf("cancel a lock using exit to close file\n");
	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.timeout = 1000;

	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	t = timeval_current();
	lock[0].pid = 2;
	req = smb_raw_lock_send(cli->tree, &io);

	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);

	printf("recv the async reply\n");
	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
	printf("async lock exit took %.2f msec\n", timeval_elapsed(&t) * 1000);
	if (timeval_elapsed(&t) > 0.1) {
		printf("failed to trigger early lock failure\n");
		return false;		
	}

done:
	return ret;
}
Exemplo n.º 5
0
bool torture_samba3_posixtimedlock(struct torture_context *tctx, struct smbcli_state *cli)
{
	NTSTATUS status;
	bool ret = true;
	const char *dirname = "posixlock";
	const char *fname = "locked";
	const char *fpath;
	const char *localdir;
	const char *localname;
	int fnum = -1;

	int fd = -1;
	struct flock posix_lock;

	union smb_lock io;
	struct smb_lock_entry lock_entry;
	struct smbcli_request *req;
	struct lock_result_state lock_result;

	struct tevent_timer *te;

	torture_assert(tctx, torture_setup_dir(cli, dirname), "creating test directory");

	if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}
	fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_warning(tctx, "Could not create file %s: %s\n", fpath,
				smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
		torture_warning(tctx, "Need 'localdir' setting\n");
		ret = false;
		goto done;
	}

	if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
					  fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}

	/*
	 * Lock a byte range from posix
	 */

	fd = open(localname, O_RDWR);
	if (fd == -1) {
		torture_warning(tctx, "open(%s) failed: %s\n",
				localname, strerror(errno));
		goto done;
	}

	posix_lock.l_type = F_WRLCK;
	posix_lock.l_whence = SEEK_SET;
	posix_lock.l_start = 0;
	posix_lock.l_len = 1;

	if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
		torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
		ret = false;
		goto done;
	}

	/*
	 * Try a cifs brlock without timeout to see if posix locking = yes
	 */

	io.lockx.in.ulock_cnt = 0;
	io.lockx.in.lock_cnt = 1;

	lock_entry.count = 1;
	lock_entry.offset = 0;
	lock_entry.pid = cli->tree->session->pid;

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
	io.lockx.in.timeout = 0;
	io.lockx.in.locks = &lock_entry;
	io.lockx.in.file.fnum = fnum;

	status = smb_raw_lock(cli->tree, &io);

	ret = true;
	CHECK_STATUS(tctx, status, NT_STATUS_FILE_LOCK_CONFLICT);

	if (!ret) {
		goto done;
	}

	/*
	 * Now fire off a timed brlock, unlock the posix lock and see if the
	 * timed lock gets through.
	 */

	io.lockx.in.timeout = 5000;

	req = smb_raw_lock_send(cli->tree, &io);
	if (req == NULL) {
		torture_warning(tctx, "smb_raw_lock_send failed\n");
		ret = false;
		goto done;
	}

	lock_result.done = false;
	req->async.fn = receive_lock_result;
	req->async.private_data = &lock_result;

	te = tevent_add_timer(tctx->ev,
			      tctx, timeval_current_ofs(1, 0),
			      close_locked_file, &fd);
	if (te == NULL) {
		torture_warning(tctx, "tevent_add_timer failed\n");
		ret = false;
		goto done;
	}

	while ((fd != -1) || (!lock_result.done)) {
		if (tevent_loop_once(tctx->ev) == -1) {
			torture_warning(tctx, "tevent_loop_once failed: %s\n",
					strerror(errno));
			ret = false;
			goto done;
		}
	}

	CHECK_STATUS(tctx, lock_result.status, NT_STATUS_OK);

 done:
	if (fnum != -1) {
		smbcli_close(cli->tree, fnum);
	}
	if (fd != -1) {
		close(fd);
	}
	smbcli_deltree(cli->tree, dirname);
	return ret;
}