ltp.lists.linux.it archive mirror
 help / color / mirror / Atom feed
From: Alexander Aring <aahringo@redhat.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH 1/5] fcntl40: test for owner values on classic posix lock
Date: Tue, 30 May 2023 16:37:03 -0400	[thread overview]
Message-ID: <20230530203707.2965684-2-aahringo@redhat.com> (raw)
In-Reply-To: <20230530203707.2965684-1-aahringo@redhat.com>

This patch adds fcntl40 to test similar owner values for classical owner
locks. There was an issue been found in the gfs2 filesystem because
there can be collisions with identical owner values.

Signed-off-by: Alexander Aring <aahringo@redhat.com>
---
 testcases/kernel/syscalls/fcntl/.gitignore |   2 +
 testcases/kernel/syscalls/fcntl/Makefile   |   3 +
 testcases/kernel/syscalls/fcntl/fcntl40.c  | 188 +++++++++++++++++++++
 3 files changed, 193 insertions(+)
 create mode 100644 testcases/kernel/syscalls/fcntl/fcntl40.c

diff --git a/testcases/kernel/syscalls/fcntl/.gitignore b/testcases/kernel/syscalls/fcntl/.gitignore
index 10cb0995f..e558cfe83 100644
--- a/testcases/kernel/syscalls/fcntl/.gitignore
+++ b/testcases/kernel/syscalls/fcntl/.gitignore
@@ -74,3 +74,5 @@
 /fcntl38_64
 /fcntl39
 /fcntl39_64
+/fcntl40
+/fcntl40_64
diff --git a/testcases/kernel/syscalls/fcntl/Makefile b/testcases/kernel/syscalls/fcntl/Makefile
index df663a50a..c3196a527 100644
--- a/testcases/kernel/syscalls/fcntl/Makefile
+++ b/testcases/kernel/syscalls/fcntl/Makefile
@@ -12,6 +12,9 @@ fcntl34_64: LDLIBS += -lpthread
 fcntl36: LDLIBS += -lpthread
 fcntl36_64: LDLIBS += -lpthread
 
+fcntl40: LDLIBS += -lpthread
+fcntl40_64: LDLIBS += -lpthread
+
 include $(top_srcdir)/include/mk/testcases.mk
 include $(abs_srcdir)/../utils/newer_64.mk
 
diff --git a/testcases/kernel/syscalls/fcntl/fcntl40.c b/testcases/kernel/syscalls/fcntl/fcntl40.c
new file mode 100644
index 000000000..829685436
--- /dev/null
+++ b/testcases/kernel/syscalls/fcntl/fcntl40.c
@@ -0,0 +1,188 @@
+/*
+ * [Description]
+ * Tests gfs2 dlm posix op queue handling in the kernel.
+ * It is recommended to run watch -n 0.1 "dlm_tool plocks $LS"
+ * aside to monitor dlm plock handling.
+ *
+ * [How to use it]
+ * Call it with TMPDIR=/mnt ./fcntl40 where TMPDIR is a gfs2 mountpoint.
+ * Try it on other filesystems to compare results.
+ *
+ * [What's it doing]
+ *
+ * The test shows that we currently have problems with the operation lookup
+ * functionality [0] when we using threads. The owner value is the same for two
+ * locks being in WAITING state. dlm_controld "dlm_tool plocks $LS" will show
+ * it correctly that the specific lock is not in waiting anymore. The issue
+ * begins matching the right iter->done in the kernel at dev_write() see [0].
+ *
+ * What this test does is (using dlm_controld interval range interpretation):
+ *
+ * parent:
+ *
+ * 1. lock[0-1]
+ *
+ * child:
+ *
+ * thread1:
+ *
+ * 2. lockw[1-1] - important 1-1 at first because the order of WAITING state
+ *                 locks matters
+ *
+ * thread2:
+ *
+ * 3. lockw[0-0]
+ *
+ * parent:
+ *
+ * 4. unlock[1-1] - will give a iter->done = 1 in [0] for lock at 3. and the
+ *                  application results in a deadlock
+ * 5. unlock[0-0]
+ *
+ * We have this issue also with SETLK, GETLK - it's easier to reproduce
+ * with SETLKW because dev_write() is more controlable by doing unlocks.
+ *
+ * OFD (open filedescriptor locks) are also affected and should be able
+ * to reproduce with fork() only and not threads. The owner value of [0]
+ * depends on "struct file *" pointer in this case.
+ *
+ * [0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/dlm/plock.c?h=v6.3#n432
+ */
+
+#include <sys/wait.h>
+#include <pthread.h>
+
+#include "tst_safe_pthread.h"
+#include "tst_test.h"
+
+static int fd;
+
+static void *do_thread1(void *arg)
+{
+	const struct flock fl_0_0 = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_SET,
+		.l_start = 0L,
+		.l_len = 1L,
+	};
+	(void)arg;
+
+	tst_res(TINFO, "thread1 waits for thread2 to lock 1-1");
+	TST_CHECKPOINT_WAIT(1);
+
+	tst_res(TINFO, "thread1 lock region 0-0 - It should block");
+	SAFE_FCNTL(fd, F_SETLKW, &fl_0_0);
+	tst_res(TINFO, "lock region 0-0 acquired");
+
+	return NULL;
+}
+
+static void *do_thread2(void *arg)
+{
+	const struct flock fl_1_1 = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_SET,
+		.l_start = 1L,
+		.l_len = 1L,
+	};
+	(void)arg;
+
+	tst_res(TINFO, "thread1 lock region 1-1 - It should block");
+	SAFE_FCNTL(fd, F_SETLKW, &fl_1_1);
+	tst_res(TINFO, "lock region 1-1 acquired");
+
+	TST_CHECKPOINT_WAKE(2);
+
+	return NULL;
+}
+
+void do_child(void)
+{
+	pthread_t t1, t2;
+
+	SAFE_PTHREAD_CREATE(&t1, NULL, do_thread1, NULL);
+	SAFE_PTHREAD_CREATE(&t2, NULL, do_thread2, NULL);
+
+	SAFE_PTHREAD_JOIN(t1, NULL);
+	SAFE_PTHREAD_JOIN(t2, NULL);
+
+	tst_res(TPASS, "Child passed!");
+}
+
+void do_parent(void)
+{
+	struct flock fl = {
+		.l_whence = SEEK_SET,
+	};
+
+	/* wait for 1 seconds so thread2 lock 1-1 tries to acquires at first
+	 * than thread1 lock 0-0 tries to acquired to have a specific waiting
+	 * order in dlm posix handling.
+	 */
+	sleep(1);
+	/* tell thread2 to call SETLKW for lock 0-0 */
+	TST_CHECKPOINT_WAKE(1);
+	/* wait 3 seconds for thread 1 and 2 being in waiting state */
+	sleep(3);
+
+	/* unlock 0-1, should be successful */
+	fl.l_type = F_UNLCK;
+	fl.l_start = 1;
+	fl.l_len = 1;
+	tst_res(TINFO, "unlock region 1-1 thread2");
+	SAFE_FCNTL(fd, F_SETLK, &fl);
+
+	/* wait until thread 2 got acquired and leave waiting */
+	TST_CHECKPOINT_WAIT(2);
+
+	fl.l_start = 0;
+	fl.l_len = 1;
+	fl.l_type = F_UNLCK;
+	tst_res(TINFO, "unlock region 0-0 thread2");
+	SAFE_FCNTL(fd, F_SETLK, &fl);
+}
+
+static void fcntl40_test(void)
+{
+	struct flock fl = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_SET,
+		.l_start = 0L,
+		.l_len = 2L,
+	};
+	pid_t pid;
+
+	tst_res(TINFO, "parent lock region 0-1 - should be successful");
+	SAFE_FCNTL(fd, F_SETLK, &fl);
+	tst_res(TINFO, "parent region 0-1 locked");
+
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		do_child();
+		return;
+	}
+
+	do_parent();
+	wait(NULL);
+
+	tst_res(TPASS, "Parent passed!");
+}
+
+static void setup(void)
+{
+	fd = SAFE_OPEN("filename", O_RDWR | O_CREAT, 0700);
+}
+
+static void cleanup(void)
+{
+	if (fd > -1)
+		SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.test_all = fcntl40_test,
+	.setup = setup,
+	.cleanup = cleanup,
+};
-- 
2.31.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

  reply	other threads:[~2023-05-30 20:38 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-30 20:37 [LTP] [PATCH 0/5] fcntl: add more testcases Alexander Aring
2023-05-30 20:37 ` Alexander Aring [this message]
2023-06-21  9:03   ` [LTP] [PATCH 1/5] fcntl40: test for owner values on classic posix lock Petr Vorel
2023-06-30 19:59     ` Alexander Aring
2023-07-02 19:18       ` Petr Vorel
2023-07-05 13:23         ` Alexander Aring
2023-07-07  8:14           ` Petr Vorel
2023-07-07 12:50             ` Alexander Aring
2023-07-07 13:17               ` Petr Vorel
2023-07-02 19:19       ` Petr Vorel
2023-05-30 20:37 ` [LTP] [PATCH 2/5] fcntl41: test for owner values on OFD posix locks Alexander Aring
2023-06-21  9:38   ` Petr Vorel
2023-06-30 20:00     ` Alexander Aring
2023-05-30 20:37 ` [LTP] [PATCH 3/5] fcntl42: test for F_SETLKW interruption case Alexander Aring
2023-05-30 20:37 ` [LTP] [PATCH 4/5] fcntl43: test for identical F_SETLKW lock requests Alexander Aring
2023-05-30 20:37 ` [LTP] [PATCH 5/5] fcntl44: test for kill child while others waiting Alexander Aring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230530203707.2965684-2-aahringo@redhat.com \
    --to=aahringo@redhat.com \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).