[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sun Dec 22 18:58:02 UTC 2019


The branch, master has been updated
       via  40ecc2f6f01 lib: Fix contending with a READ lock
       via  12638d48a63 torture3: Add a test that contends with a READ, not a WRITE lock
       via  bc00eaca703 torture3: Parametrize lock4_child()s locktype
       via  bf592a19059 torture3: Introduce "key" helper variable
      from  30f9e1dd596 vfs_zfsacl: fix issue with ACL inheritance in zfsacl

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 40ecc2f6f015b86b49326bff4b1cbcab8263f1ac
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 20 16:20:00 2019 +0100

    lib: Fix contending with a READ lock
    
    When contending a WRITE with an existing READ, the contender puts
    himself into the exclusive slot, waiting for the READers to go
    away. If the async lock request is canceled before we got the lock, we
    need to remove ourselves again. This is done in the destructor of the
    g_lock_lock_state. In the successful case, the destructor needs to go
    away.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Sun Dec 22 18:57:17 UTC 2019 on sn-devel-184

commit 12638d48a63e90d7d5568d00e39c7041f96675ae
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 22 14:05:17 2019 +0100

    torture3: Add a test that contends with a READ, not a WRITE lock
    
    This walks different code paths in the subsequent locker. And the one
    that we did not test so far is in fact buggy
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit bc00eaca703be97709d0706f746930b3a13bb44b
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 22 14:01:07 2019 +0100

    torture3: Parametrize lock4_child()s locktype
    
    We'll call it twice soon
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit bf592a1905984042aeb57ddef654229ffb2ee39b
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Dec 21 10:47:37 2019 +0100

    torture3: Introduce "key" helper variable
    
    Call string_term_tdb_data() once instead of three times
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/lib/g_lock.c          |   2 +
 source3/selftest/tests.py     |   1 +
 source3/torture/proto.h       |   1 +
 source3/torture/test_g_lock.c | 162 ++++++++++++++++++++++++++++++++++++++----
 source3/torture/torture.c     |   4 ++
 5 files changed, 157 insertions(+), 13 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index 1f4dcda2605..4bf30188a43 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -419,6 +419,8 @@ static NTSTATUS g_lock_trylock(
 			return NT_STATUS_LOCK_NOT_GRANTED;
 		}
 
+		talloc_set_destructor(req_state, NULL);
+
 		/*
 		 * Retry after a conflicting lock was released
 		 */
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 25aa08a79f5..7f51d344bab 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -220,6 +220,7 @@ local_tests = [
     "LOCAL-G-LOCK2",
     "LOCAL-G-LOCK3",
     "LOCAL-G-LOCK4",
+    "LOCAL-G-LOCK4A",
     "LOCAL-G-LOCK5",
     "LOCAL-G-LOCK6",
     "LOCAL-G-LOCK7",
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 48c127c30d5..73a28991735 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -135,6 +135,7 @@ 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_lock4a(int dummy);
 bool run_g_lock5(int dummy);
 bool run_g_lock6(int dummy);
 bool run_g_lock7(int dummy);
diff --git a/source3/torture/test_g_lock.c b/source3/torture/test_g_lock.c
index c720e7d6612..05b6cecfc41 100644
--- a/source3/torture/test_g_lock.c
+++ b/source3/torture/test_g_lock.c
@@ -333,7 +333,9 @@ fail:
 }
 
 static bool lock4_child(const char *lockname,
-			int ready_pipe, int exit_pipe)
+			enum g_lock_type lock_type,
+			int ready_pipe,
+			int exit_pipe)
 {
 	struct tevent_context *ev = NULL;
 	struct messaging_context *msg = NULL;
@@ -347,8 +349,11 @@ static bool lock4_child(const char *lockname,
 		return false;
 	}
 
-	status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_WRITE,
-			     (struct timeval) { .tv_sec = 1 });
+	status = g_lock_lock(
+		ctx,
+		string_term_tdb_data(lockname),
+		lock_type,
+		(struct timeval) { .tv_sec = 1 });
 	if (!NT_STATUS_IS_OK(status)) {
 		fprintf(stderr, "child: g_lock_lock returned %s\n",
 			nt_errstr(status));
@@ -446,7 +451,7 @@ static void lock4_check(struct server_id exclusive,
 }
 
 /*
- * Test a lock conflict
+ * Test a lock conflict: Contend with a WRITE lock
  */
 
 bool run_g_lock4(int dummy)
@@ -455,6 +460,7 @@ bool run_g_lock4(int dummy)
 	struct messaging_context *msg = NULL;
 	struct g_lock_ctx *ctx = NULL;
 	const char *lockname = "lock4";
+	TDB_DATA key = string_term_tdb_data(lockname);
 	pid_t child;
 	int ready_pipe[2];
 	int exit_pipe[2];
@@ -484,7 +490,8 @@ bool run_g_lock4(int dummy)
 	if (child == 0) {
 		close(ready_pipe[0]);
 		close(exit_pipe[1]);
-		ok = lock4_child(lockname, ready_pipe[1], exit_pipe[0]);
+		ok = lock4_child(
+			lockname, G_LOCK_WRITE, ready_pipe[1], exit_pipe[0]);
 		exit(ok ? 0 : 1);
 	}
 
@@ -501,24 +508,23 @@ bool run_g_lock4(int dummy)
 		return false;
 	}
 
-	status = g_lock_lock(ctx, string_term_tdb_data(lockname), G_LOCK_WRITE,
-			     (struct timeval) { .tv_usec = 1 });
+	status = g_lock_lock(
+		ctx, key, 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, string_term_tdb_data(lockname), G_LOCK_READ,
-			     (struct timeval) { .tv_usec = 1 });
+	status = g_lock_lock(
+		ctx, key, 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, string_term_tdb_data(lockname),
-			       G_LOCK_WRITE);
+	req = g_lock_lock_send(ev, ev, ctx, key, G_LOCK_WRITE);
 	if (req == NULL) {
 		fprintf(stderr, "g_lock_lock send failed\n");
 		goto fail;
@@ -547,8 +553,138 @@ bool run_g_lock4(int dummy)
 			.me = messaging_server_id(msg)
 		};
 
-		status = g_lock_dump(ctx, string_term_tdb_data(lockname),
-				     lock4_check, &state);
+		status = g_lock_dump(ctx, key, lock4_check, &state);
+		if (!NT_STATUS_IS_OK(status)) {
+			fprintf(stderr, "g_lock_dump failed: %s\n",
+				nt_errstr(status));
+			goto fail;
+		}
+		if (!state.ok) {
+			fprintf(stderr, "lock4_check failed\n");
+			goto fail;
+		}
+	}
+
+	ret = true;
+fail:
+	TALLOC_FREE(ctx);
+	TALLOC_FREE(msg);
+	TALLOC_FREE(ev);
+	return ret;
+}
+
+/*
+ * Test a lock conflict: Contend with a READ lock
+ */
+
+bool run_g_lock4a(int dummy)
+{
+	struct tevent_context *ev = NULL;
+	struct messaging_context *msg = NULL;
+	struct g_lock_ctx *ctx = NULL;
+	const char *lockname = "lock4a";
+	TDB_DATA key = string_term_tdb_data(lockname);
+	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, G_LOCK_READ, 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, key, 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, key, G_LOCK_READ, (struct timeval) { .tv_usec = 1 });
+	if (!NT_STATUS_IS_OK(status)) {
+		fprintf(stderr, "g_lock_lock returned %s\n",
+			nt_errstr(status));
+		goto fail;
+	}
+
+	status = g_lock_unlock(ctx, key);
+	if (!NT_STATUS_IS_OK(status)) {
+		fprintf(stderr,
+			"g_lock_unlock returned %s\n",
+			nt_errstr(status));
+		goto fail;
+	}
+
+	req = g_lock_lock_send(ev, ev, ctx, key, 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;
+		}
+	}
+
+	{
+		struct lock4_check_state state = {
+			.me = messaging_server_id(msg)
+		};
+
+		status = g_lock_dump(ctx, key, lock4_check, &state);
 		if (!NT_STATUS_IS_OK(status)) {
 			fprintf(stderr, "g_lock_dump failed: %s\n",
 				nt_errstr(status));
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index db5d07bf584..2ff735b3d22 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -14811,6 +14811,10 @@ static struct {
 		.name  = "LOCAL-G-LOCK4",
 		.fn    = run_g_lock4,
 	},
+	{
+		.name  = "LOCAL-G-LOCK4A",
+		.fn    = run_g_lock4a,
+	},
 	{
 		.name  = "LOCAL-G-LOCK5",
 		.fn    = run_g_lock5,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list