mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
torture3: Test lock conflict and cleanup
Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
2a29c5442d
commit
27eb93c04e
@ -151,6 +151,7 @@ local_tests = [
|
||||
"LOCAL-G-LOCK1",
|
||||
"LOCAL-G-LOCK2",
|
||||
"LOCAL-G-LOCK3",
|
||||
"LOCAL-G-LOCK4",
|
||||
"LOCAL-hex_encode_buf",
|
||||
"LOCAL-remove_duplicate_addrs2"]
|
||||
|
||||
|
@ -127,5 +127,6 @@ bool run_pthreadpool_tevent(int dummy);
|
||||
bool run_g_lock1(int dummy);
|
||||
bool run_g_lock2(int dummy);
|
||||
bool run_g_lock3(int dummy);
|
||||
bool run_g_lock4(int dummy);
|
||||
|
||||
#endif /* __TORTURE_H__ */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "g_lock.h"
|
||||
#include "messages.h"
|
||||
#include "lib/util/server_id.h"
|
||||
#include "lib/util/sys_rw.h"
|
||||
|
||||
static bool get_g_lock_ctx(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context **ev,
|
||||
@ -311,6 +312,187 @@ bool run_g_lock3(int dummy)
|
||||
}
|
||||
|
||||
|
||||
ret = true;
|
||||
fail:
|
||||
TALLOC_FREE(ctx);
|
||||
TALLOC_FREE(msg);
|
||||
TALLOC_FREE(ev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool lock4_child(const char *lockname,
|
||||
int ready_pipe, int exit_pipe)
|
||||
{
|
||||
struct tevent_context *ev = NULL;
|
||||
struct messaging_context *msg = NULL;
|
||||
struct g_lock_ctx *ctx = NULL;
|
||||
NTSTATUS status;
|
||||
ssize_t n;
|
||||
bool ok;
|
||||
|
||||
ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
status = g_lock_lock(ctx, lockname, G_LOCK_WRITE,
|
||||
(struct timeval) { .tv_sec = 1 });
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
fprintf(stderr, "child: g_lock_lock returned %s\n",
|
||||
nt_errstr(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
n = sys_write(ready_pipe, &ok, sizeof(ok));
|
||||
if (n != sizeof(ok)) {
|
||||
fprintf(stderr, "child: write failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
n = sys_read(exit_pipe, &ok, sizeof(ok));
|
||||
if (n != 0) {
|
||||
fprintf(stderr, "child: read failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void lock4_done(struct tevent_req *subreq)
|
||||
{
|
||||
int *done = tevent_req_callback_data_void(subreq);
|
||||
NTSTATUS status;
|
||||
|
||||
status = g_lock_lock_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
fprintf(stderr, "g_lock_lock_recv returned %s\n",
|
||||
nt_errstr(status));
|
||||
*done = -1;
|
||||
return;
|
||||
}
|
||||
*done = 1;
|
||||
}
|
||||
|
||||
static void lock4_waited(struct tevent_req *subreq)
|
||||
{
|
||||
int *exit_pipe = tevent_req_callback_data_void(subreq);
|
||||
pid_t child;
|
||||
int status;
|
||||
bool ok;
|
||||
|
||||
printf("waited\n");
|
||||
|
||||
ok = tevent_wakeup_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "tevent_wakeup_recv failed\n");
|
||||
}
|
||||
close(*exit_pipe);
|
||||
|
||||
child = wait(&status);
|
||||
|
||||
printf("child %d exited with %d\n", (int)child, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test a lock conflict
|
||||
*/
|
||||
|
||||
bool run_g_lock4(int dummy)
|
||||
{
|
||||
struct tevent_context *ev = NULL;
|
||||
struct messaging_context *msg = NULL;
|
||||
struct g_lock_ctx *ctx = NULL;
|
||||
const char *lockname = "lock4";
|
||||
pid_t child;
|
||||
int ready_pipe[2];
|
||||
int exit_pipe[2];
|
||||
NTSTATUS status;
|
||||
bool ret = false;
|
||||
struct tevent_req *req;
|
||||
bool ok;
|
||||
int done;
|
||||
|
||||
if ((pipe(ready_pipe) != 0) || (pipe(exit_pipe) != 0)) {
|
||||
perror("pipe failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
child = fork();
|
||||
|
||||
ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx);
|
||||
if (!ok) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (child == -1) {
|
||||
perror("fork failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (child == 0) {
|
||||
close(ready_pipe[0]);
|
||||
close(exit_pipe[1]);
|
||||
ok = lock4_child(lockname, ready_pipe[1], exit_pipe[0]);
|
||||
exit(ok ? 0 : 1);
|
||||
}
|
||||
|
||||
close(ready_pipe[1]);
|
||||
close(exit_pipe[0]);
|
||||
|
||||
if (sys_read(ready_pipe[0], &ok, sizeof(ok)) != sizeof(ok)) {
|
||||
perror("read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
fprintf(stderr, "child returned error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
status = g_lock_lock(ctx, lockname, G_LOCK_WRITE,
|
||||
(struct timeval) { .tv_usec = 1 });
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
fprintf(stderr, "g_lock_lock returned %s\n",
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = g_lock_lock(ctx, lockname, G_LOCK_READ,
|
||||
(struct timeval) { .tv_usec = 1 });
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
fprintf(stderr, "g_lock_lock returned %s\n",
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
req = g_lock_lock_send(ev, ev, ctx, lockname, G_LOCK_WRITE);
|
||||
if (req == NULL) {
|
||||
fprintf(stderr, "g_lock_lock send failed\n");
|
||||
goto fail;
|
||||
}
|
||||
tevent_req_set_callback(req, lock4_done, &done);
|
||||
|
||||
req = tevent_wakeup_send(ev, ev, timeval_current_ofs(1, 0));
|
||||
if (req == NULL) {
|
||||
fprintf(stderr, "tevent_wakeup_send failed\n");
|
||||
goto fail;
|
||||
}
|
||||
tevent_req_set_callback(req, lock4_waited, &exit_pipe[1]);
|
||||
|
||||
done = 0;
|
||||
|
||||
while (done == 0) {
|
||||
int tevent_ret = tevent_loop_once(ev);
|
||||
if (tevent_ret != 0) {
|
||||
perror("tevent_loop_once failed");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = true;
|
||||
fail:
|
||||
TALLOC_FREE(ctx);
|
||||
|
@ -11480,6 +11480,7 @@ static struct {
|
||||
{ "LOCAL-G-LOCK1", run_g_lock1, 0 },
|
||||
{ "LOCAL-G-LOCK2", run_g_lock2, 0 },
|
||||
{ "LOCAL-G-LOCK3", run_g_lock3, 0 },
|
||||
{ "LOCAL-G-LOCK4", run_g_lock4, 0 },
|
||||
{ "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
|
||||
{ "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
|
||||
{NULL, NULL, 0}};
|
||||
|
Loading…
x
Reference in New Issue
Block a user