1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

torture3: Test blocking posix locks

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2019-06-14 21:55:09 -07:00 committed by Jeremy Allison
parent 2f1a459b74
commit b20231a1ab
3 changed files with 285 additions and 1 deletions

View File

@ -49,6 +49,7 @@
^samba3.smbtorture_s3.plain.POSIX-OFD-LOCK\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.POSIX-STREAM-DELETE\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.POSIX-MKDIR\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.POSIX-BLOCKING-LOCK\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.WINDOWS-BAD-SYMLINK\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.RENAME-ACCESS\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain.OWNER-RIGHTS\(ad_dc_ntvfs\) # Don't test against the s4 ntvfs server anymore

View File

@ -156,7 +156,9 @@ for s in shares:
plansmbtorture4testsuite(t, "simpleserver", "//%s/%s %s" % ('$SERVER_IP', s, ' -U$USERNAME%$PASSWORD'), description=s)
posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA", "POSIX-OFD-LOCK",
"POSIX-STREAM-DELETE", "WINDOWS-BAD-SYMLINK", "POSIX-MKDIR"]
"POSIX-STREAM-DELETE", "WINDOWS-BAD-SYMLINK", "POSIX-MKDIR",
"POSIX-BLOCKING-LOCK",
]
for t in posix_tests:
plantestsuite("samba3.smbtorture_s3.plain.%s" % t, "nt4_dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])

View File

@ -7479,6 +7479,283 @@ static bool run_posix_ofd_lock_test(int dummy)
return correct;
}
struct posix_blocking_state {
struct tevent_context *ev;
struct cli_state *cli1;
uint16_t fnum1;
struct cli_state *cli2;
uint16_t fnum2;
bool gotblocked;
bool gotecho;
};
static void posix_blocking_locked(struct tevent_req *subreq);
static void posix_blocking_gotblocked(struct tevent_req *subreq);
static void posix_blocking_gotecho(struct tevent_req *subreq);
static void posix_blocking_unlocked(struct tevent_req *subreq);
static struct tevent_req *posix_blocking_send(
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct cli_state *cli1,
uint16_t fnum1,
struct cli_state *cli2,
uint16_t fnum2)
{
struct tevent_req *req = NULL, *subreq = NULL;
struct posix_blocking_state *state = NULL;
req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
if (req == NULL) {
return NULL;
}
state->ev = ev;
state->cli1 = cli1;
state->fnum1 = fnum1;
state->cli2 = cli2;
state->fnum2 = fnum2;
subreq = cli_posix_lock_send(
state,
state->ev,
state->cli1,
state->fnum1,
0,
1,
false,
WRITE_LOCK);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, posix_blocking_locked, req);
return req;
}
static void posix_blocking_locked(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct posix_blocking_state *state = tevent_req_data(
req, struct posix_blocking_state);
NTSTATUS status;
status = cli_posix_lock_recv(subreq);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
subreq = cli_posix_lock_send(
state,
state->ev,
state->cli2,
state->fnum2,
0,
1,
true,
WRITE_LOCK);
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
/* Make sure the blocking request is delivered */
subreq = cli_echo_send(
state,
state->ev,
state->cli2,
1,
(DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
}
static void posix_blocking_gotblocked(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct posix_blocking_state *state = tevent_req_data(
req, struct posix_blocking_state);
NTSTATUS status;
status = cli_posix_lock_recv(subreq);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
if (!state->gotecho) {
printf("blocked req got through before echo\n");
tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
return;
}
tevent_req_done(req);
}
static void posix_blocking_gotecho(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct posix_blocking_state *state = tevent_req_data(
req, struct posix_blocking_state);
NTSTATUS status;
status = cli_echo_recv(subreq);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
if (state->gotblocked) {
printf("blocked req got through before echo\n");
tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
return;
}
state->gotecho = true;
subreq = cli_posix_lock_send(
state,
state->ev,
state->cli1,
state->fnum1,
0,
1,
false,
UNLOCK_LOCK);
if (tevent_req_nomem(subreq, req)) {
return;
}
tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
}
static void posix_blocking_unlocked(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
NTSTATUS status;
status = cli_posix_lock_recv(subreq);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
/* tevent_req_done in posix_blocking_gotlocked */
}
static NTSTATUS posix_blocking_recv(struct tevent_req *req)
{
return tevent_req_simple_recv_ntstatus(req);
}
static bool run_posix_blocking_lock(int dummy)
{
struct tevent_context *ev = NULL;
struct cli_state *cli1 = NULL, *cli2 = NULL;
const char *fname = "posix_blocking";
uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
struct tevent_req *req = NULL;
NTSTATUS status;
bool ret = false;
bool ok;
printf("Starting posix blocking lock test\n");
ev = samba_tevent_context_init(NULL);
if (ev == NULL) {
return false;
}
ok = torture_open_connection(&cli1, 0);
if (!ok) {
goto fail;
}
ok = torture_open_connection(&cli2, 0);
if (!ok) {
goto fail;
}
smbXcli_conn_set_sockopt(cli1->conn, sockops);
status = torture_setup_unix_extensions(cli1);
if (!NT_STATUS_IS_OK(status)) {
return false;
}
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
0600, &fnum1);
if (!NT_STATUS_IS_OK(status)) {
printf("First POSIX open of %s failed: %s\n",
fname,
nt_errstr(status));
goto fail;
}
status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
if (!NT_STATUS_IS_OK(status)) {
printf("Second POSIX open of %s failed: %s\n",
fname,
nt_errstr(status));
goto fail;
}
req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
if (req == NULL) {
printf("cli_posix_blocking failed\n");
goto fail;
}
ok = tevent_req_poll_ntstatus(req, ev, &status);
if (!ok) {
printf("tevent_req_poll_ntstatus failed: %s\n",
nt_errstr(status));
goto fail;
}
status = posix_blocking_recv(req);
TALLOC_FREE(req);
if (!NT_STATUS_IS_OK(status)) {
printf("posix_blocking_recv returned %s\n",
nt_errstr(status));
goto fail;
}
ret = true;
fail:
if (fnum1 != UINT16_MAX) {
cli_close(cli1, fnum1);
fnum1 = UINT16_MAX;
}
if (fnum2 != UINT16_MAX) {
cli_close(cli2, fnum2);
fnum2 = UINT16_MAX;
}
if (cli1 != NULL) {
cli_setatr(cli1, fname, 0, 0);
cli_posix_unlink(cli1, fname);
}
ok = true;
if (cli1 != NULL) {
ok &= torture_close_connection(cli1);
cli1 = NULL;
}
if (cli2 != NULL) {
ok &= torture_close_connection(cli2);
cli2 = NULL;
}
if (!ok) {
ret = false;
}
TALLOC_FREE(ev);
return ret;
}
/*
Test POSIX mkdir is case-sensitive.
*/
@ -12400,6 +12677,10 @@ static struct {
.name = "POSIX-OFD-LOCK",
.fn = run_posix_ofd_lock_test,
},
{
.name = "POSIX-BLOCKING-LOCK",
.fn = run_posix_blocking_lock,
},
{
.name = "POSIX-MKDIR",
.fn = run_posix_mkdir_test,