diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-08-30 09:51:33 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 15:03:12 -0500 |
commit | afe87d6cfc7e13005b1a5b8b8110e480410bb4a0 (patch) | |
tree | bb16f6bafbc4147c85c7cbba8f67983c2cc4663f /source4/torture/raw | |
parent | d510accb39f07ae0abfa0b5cdf2e834a41872cde (diff) | |
download | samba-afe87d6cfc7e13005b1a5b8b8110e480410bb4a0.tar.gz samba-afe87d6cfc7e13005b1a5b8b8110e480410bb4a0.tar.bz2 samba-afe87d6cfc7e13005b1a5b8b8110e480410bb4a0.zip |
r24798: RAW-SAMBA3POSIXTIMEDLOCK
This adds the torture:localdir option, smbtorture expects the share to actually
reside in this directory. This might open up more solid posix vs cifs tests.
(This used to be commit b0a40dd277c343f5c77c851b26981ddd8166f6bb)
Diffstat (limited to 'source4/torture/raw')
-rw-r--r-- | source4/torture/raw/raw.c | 2 | ||||
-rw-r--r-- | source4/torture/raw/samba3misc.c | 151 |
2 files changed, 153 insertions, 0 deletions
diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c index 598241b178..0c4a28e0d6 100644 --- a/source4/torture/raw/raw.c +++ b/source4/torture/raw/raw.c @@ -67,6 +67,8 @@ NTSTATUS torture_raw_init(void) torture_suite_add_simple_test(suite, "SAMBA3BADPATH", torture_samba3_badpath); torture_suite_add_simple_test(suite, "SAMBA3CASEINSENSITIVE", torture_samba3_caseinsensitive); + torture_suite_add_simple_test(suite, "SAMBA3POSIXTIMEDLOCK", + torture_samba3_posixtimedlock); torture_suite_add_simple_test(suite, "SCAN-EAMAX", torture_max_eas); suite->description = talloc_strdup(suite, diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 52ace05314..e1b1fcaf6d 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -24,6 +24,7 @@ #include "system/filesys.h" #include "libcli/libcli.h" #include "torture/util.h" +#include "lib/events/events.h" #define CHECK_STATUS(status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ @@ -665,3 +666,153 @@ BOOL torture_samba3_caseinsensitive(struct torture_context *torture) talloc_free(mem_ctx); return ret; } + +/* + * Check that Samba3 correctly deals with conflicting posix byte range locks + * on an underlying file + */ + +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; + + if (!torture_open_connection(&cli, 0)) { + ret = False; + goto done; + } + + smbcli_deltree(cli->tree, dirname); + + status = smbcli_mkdir(cli->tree, dirname); + if (!NT_STATUS_IS_OK(status)) { + torture_warning(tctx, "smbcli_mkdir failed: %s\n", + nt_errstr(status)); + ret = False; + goto done; + } + + 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(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; + } + + /* + * Ship the async timed request to the server + */ + event_loop_once(req->transport->socket->event.ctx); + msleep(500); + + close(fd); + + status = smbcli_request_simple_recv(req); + + CHECK_STATUS(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; +} |