summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2017-05-25 10:48:15 +0200
committerVolker Lendecke <vl@samba.org>2017-06-15 13:19:15 +0200
commit2c200dd00d8a3969e5dbbdb0598b5073fd3cf65e (patch)
tree18c4dd3eee0f379a2ef6c581496123bc9743b754 /source3
parentd19e7709d9b6666f53ccfec47a86f0f0cab70925 (diff)
downloadsamba-2c200dd00d8a3969e5dbbdb0598b5073fd3cf65e.tar.gz
torture3: Test heuristic cleanup
Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rwxr-xr-xsource3/selftest/tests.py1
-rw-r--r--source3/torture/proto.h1
-rw-r--r--source3/torture/test_g_lock.c142
-rw-r--r--source3/torture/torture.c1
4 files changed, 145 insertions, 0 deletions
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 8a8a62d1fb6..965ad7eee3e 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -152,6 +152,7 @@ local_tests = [
"LOCAL-G-LOCK2",
"LOCAL-G-LOCK3",
"LOCAL-G-LOCK4",
+ "LOCAL-G-LOCK5",
"LOCAL-hex_encode_buf",
"LOCAL-remove_duplicate_addrs2"]
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index c945d92038c..6d5ca7747e1 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -128,5 +128,6 @@ bool run_g_lock1(int dummy);
bool run_g_lock2(int dummy);
bool run_g_lock3(int dummy);
bool run_g_lock4(int dummy);
+bool run_g_lock5(int dummy);
#endif /* __TORTURE_H__ */
diff --git a/source3/torture/test_g_lock.c b/source3/torture/test_g_lock.c
index 98fd01312f8..ca373123e11 100644
--- a/source3/torture/test_g_lock.c
+++ b/source3/torture/test_g_lock.c
@@ -500,3 +500,145 @@ fail:
TALLOC_FREE(ev);
return ret;
}
+
+struct lock5_parser_state {
+ size_t num_locks;
+};
+
+static void lock5_parser(const struct g_lock_rec *locks,
+ size_t num_locks,
+ const uint8_t *data,
+ size_t datalen,
+ void *private_data)
+{
+ struct lock5_parser_state *state = private_data;
+ state->num_locks = num_locks;
+}
+
+/*
+ * Test heuristic cleanup
+ */
+
+bool run_g_lock5(int dummy)
+{
+ struct tevent_context *ev = NULL;
+ struct messaging_context *msg = NULL;
+ struct g_lock_ctx *ctx = NULL;
+ const char *lockname = "lock5";
+ pid_t child;
+ int exit_pipe[2], ready_pipe[2];
+ NTSTATUS status;
+ size_t i, nprocs;
+ int ret;
+ bool ok;
+ ssize_t nread;
+ char c;
+
+ nprocs = 5;
+
+ if ((pipe(exit_pipe) != 0) || (pipe(ready_pipe) != 0)) {
+ perror("pipe failed");
+ return false;
+ }
+
+ ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx);
+ if (!ok) {
+ fprintf(stderr, "get_g_lock_ctx failed");
+ return false;
+ }
+
+ for (i=0; i<nprocs; i++) {
+
+ child = fork();
+
+ if (child == -1) {
+ perror("fork failed");
+ return false;
+ }
+
+ if (child == 0) {
+ TALLOC_FREE(ctx);
+ TALLOC_FREE(msg);
+ TALLOC_FREE(ev);
+
+ close(ready_pipe[0]);
+ close(exit_pipe[1]);
+
+ ok = get_g_lock_ctx(talloc_tos(), &ev, &msg, &ctx);
+ if (!ok) {
+ fprintf(stderr, "get_g_lock_ctx failed");
+ exit(1);
+ }
+ status = g_lock_lock(ctx, lockname, G_LOCK_READ,
+ (struct timeval) { .tv_sec = 1 });
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr,
+ "child g_lock_lock failed %s\n",
+ nt_errstr(status));
+ exit(1);
+ }
+ close(ready_pipe[1]);
+ nread = sys_read(exit_pipe[0], &c, sizeof(c));
+ if (nread != 0) {
+ fprintf(stderr, "sys_read returned %zu (%s)\n",
+ nread, strerror(errno));
+ exit(1);
+ }
+ exit(0);
+ }
+ }
+
+ close(ready_pipe[1]);
+
+ nread = sys_read(ready_pipe[0], &c, sizeof(c));
+ if (nread != 0) {
+ fprintf(stderr, "sys_read returned %zu (%s)\n",
+ nread, strerror(errno));
+ return false;
+ }
+
+ close(exit_pipe[1]);
+
+ for (i=0; i<nprocs; i++) {
+ int child_status;
+ ret = waitpid(-1, &child_status, 0);
+ if (ret == -1) {
+ perror("waitpid failed");
+ return false;
+ }
+ }
+
+ for (i=0; i<nprocs; i++) {
+ struct lock5_parser_state state;
+
+ status = g_lock_dump(ctx, lockname, lock5_parser, &state);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr, "g_lock_dump returned %s\n",
+ nt_errstr(status));
+ return false;
+ }
+
+ if (state.num_locks != (nprocs - i)) {
+ fprintf(stderr, "nlocks=%zu, expected %zu\n",
+ state.num_locks, (nprocs-i));
+ return false;
+ }
+
+ status = g_lock_lock(ctx, lockname, G_LOCK_READ,
+ (struct timeval) { .tv_sec = 1 });
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr, "g_lock_lock failed %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ status = g_lock_unlock(ctx, lockname);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr, "g_lock_unlock failed %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ }
+
+
+ return true;
+}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 81d180e5a36..2d4b62de860 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -11481,6 +11481,7 @@ static struct {
{ "LOCAL-G-LOCK2", run_g_lock2, 0 },
{ "LOCAL-G-LOCK3", run_g_lock3, 0 },
{ "LOCAL-G-LOCK4", run_g_lock4, 0 },
+ { "LOCAL-G-LOCK5", run_g_lock5, 0 },
{ "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
{ "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
{NULL, NULL, 0}};