All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: fstests@vger.kernel.org
Cc: bfields@fieldses.org, amir73il@gmail.com
Subject: [PATCH v2] generic: Add a test for basic F_SETLEASE functionality
Date: Wed,  4 Sep 2019 08:48:49 -0400	[thread overview]
Message-ID: <20190904124849.15816-1-jlayton@kernel.org> (raw)
In-Reply-To: <20190827123537.18794-1-jlayton@kernel.org>

Add a new test that verifies that F_SETLEASE works as expected. The
parent opens a file and sets a lease on it and then forks. The child
then does a (possibly) conflicting open. We then verify that we get
signals as expected.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 .gitignore            |   1 +
 src/Makefile          |   2 +-
 src/t_setlease.c      | 165 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/566     |  51 +++++++++++++
 tests/generic/566.out |   2 +
 tests/generic/group   |   1 +
 6 files changed, 221 insertions(+), 1 deletion(-)
 create mode 100644 src/t_setlease.c
 create mode 100755 tests/generic/566
 create mode 100644 tests/generic/566.out

v2: address Eryu's comments

diff --git a/.gitignore b/.gitignore
index c8c815f91dd5..cc4c4c26ab98 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,6 +141,7 @@
 /src/t_readdir_1
 /src/t_readdir_2
 /src/t_rename_overwrite
+/src/t_setlease
 /src/t_stripealign
 /src/t_truncate_cmtime
 /src/t_truncate_self
diff --git a/src/Makefile b/src/Makefile
index c4fcf370431f..11190afa3603 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -28,7 +28,7 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
 	attr-list-by-handle-cursor-test listxattr dio-interleaved t_dir_type \
 	dio-invalidate-cache stat_test t_encrypted_d_revalidate \
 	attr_replace_test swapon mkswap t_attr_corruption t_open_tmpfiles \
-	fscrypt-crypt-util bulkstat_null_ocount
+	fscrypt-crypt-util bulkstat_null_ocount t_setlease
 
 SUBDIRS = log-writes perf
 
diff --git a/src/t_setlease.c b/src/t_setlease.c
new file mode 100644
index 000000000000..030ffaf454df
--- /dev/null
+++ b/src/t_setlease.c
@@ -0,0 +1,165 @@
+/*
+ * t_setlease.c: test basic F_SETLEASE functionality
+ *
+ * Open file, set lease on it. Then fork off children that open the file with
+ * different openflags. Ensure we get signals as expected.
+ *
+ * Copyright (c) 2019: Jeff Layton <jlayton@redhat.com>
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static volatile bool signalled;
+
+struct leasetest {
+	int	openflags;
+	int	leasetype;
+	int	conf_openflags;
+	bool	expect_signal;
+};
+
+static struct leasetest testcase[] = {
+	{ O_RDONLY, F_RDLCK, O_RDONLY, false },
+	{ O_RDONLY, F_RDLCK, O_WRONLY, true },
+	{ O_WRONLY, F_WRLCK, O_RDONLY, true },
+	{ O_WRONLY, F_WRLCK, O_WRONLY, true },
+};
+
+static void usage()
+{
+	printf("Usage: t_setlease <filename>\n");
+}
+
+static void lease_break(int signum)
+{
+	if (signum == SIGIO)
+		signalled = true;
+}
+
+/* Open/create a file, set up signal handler and set lease on file. */
+static int setlease(const char *fname, int openflags, int leasetype)
+{
+	int fd, ret;
+
+	fd = open(fname, openflags | O_CREAT, 0644);
+	if (fd < 0) {
+		perror("open");
+		return -errno;
+	}
+
+	ret = fcntl(fd, F_SETLEASE, leasetype);
+	if (ret) {
+		perror("setlease");
+		return -errno;
+	}
+	return fd;
+}
+
+static int open_conflict(const char *fname, int openflags)
+{
+	int fd;
+
+	fd = open(fname, openflags);
+	if (fd < 0) {
+		perror("open");
+		return -errno;
+	}
+	close(fd);
+	return 0;
+}
+
+static int simple_lease_break(const char *fname, struct leasetest *test)
+{
+	int fd, ret, status;
+	pid_t pid, exited;
+
+	signalled = false;
+	fd = setlease(fname, test->openflags, test->leasetype);
+	if (fd < 0)
+		return fd;
+
+	pid = fork();
+	if (pid < 0) {
+		return -errno;
+	} else if (pid == 0) {
+		/* child */
+		close(fd);
+		ret = open_conflict(fname, test->conf_openflags);
+		exit(ret ? 1 : 0);
+	}
+
+	/* parent */
+	while (!signalled) {
+		/* Break out if child exited */
+		exited = waitpid(pid, &status, WNOHANG);
+		if (exited)
+			break;
+		usleep(1000);
+	}
+
+	ret = fcntl(fd, F_SETLEASE, F_UNLCK);
+	if (ret) {
+		perror("F_UNLCK");
+		return ret;
+	}
+
+	close(fd);
+
+	/* If it didn't already exit, then wait now */
+	if (!exited)
+		waitpid(pid, &status, 0);
+
+	if (!WIFEXITED(status)) {
+		ret = 1;
+	} else {
+		ret = WEXITSTATUS(status);
+		if (test->expect_signal != signalled)
+			ret = 1;
+	}
+
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	int ret, i;
+	char *fname;
+	struct sigaction sa = { .sa_handler = lease_break };
+
+	if (argc < 2) {
+		usage();
+		return 1;
+	}
+
+	fname = argv[1];
+
+	ret = sigaction(SIGIO, &sa, NULL);
+	if (ret) {
+		perror("sigaction");
+		return -1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(testcase); ++i) {
+		struct leasetest *t = &testcase[i];
+
+		ret = simple_lease_break(fname, t);
+		if (ret) {
+			fprintf(stderr,
+				"Test failure: openflags=%d leasetype=%d conf_openflags=%d expect_signal=%d\n",
+				t->openflags, t->leasetype, t->conf_openflags,
+				t->expect_signal);
+			exit(1);
+		}
+	}
+	return 0;
+}
diff --git a/tests/generic/566 b/tests/generic/566
new file mode 100755
index 000000000000..f08cea833681
--- /dev/null
+++ b/tests/generic/566
@@ -0,0 +1,51 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019 Jeff Layton.  All Rights Reserved.
+#
+# FS QA Test 566
+#
+# Test basic F_SETLEASE functionality. Call the t_setlease program which
+# opens a file and sets a lease on it, and then forks a child to open the
+# same file with various openflags and verify that we get signals as expected.
+#
+# Note that kernels that lack 387e3746d01c (locks: eliminate false positive
+# conflicts for write lease) will fail this test as tasks that have the file
+# open for write are unable to get a F_WRLCK lease.
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_supported_os Linux
+_require_test
+_require_test_program t_setlease
+
+testfile=$TEST_DIR/t_setlease-testfile
+$here/src/t_setlease $testfile
+
+# success, all done
+echo "Silence is golden"
+status=0
+exit
diff --git a/tests/generic/566.out b/tests/generic/566.out
new file mode 100644
index 000000000000..31df95af2378
--- /dev/null
+++ b/tests/generic/566.out
@@ -0,0 +1,2 @@
+QA output created by 566
+Silence is golden
diff --git a/tests/generic/group b/tests/generic/group
index 2e4a6f79276b..57f85f619f3b 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -568,3 +568,4 @@
 563 auto quick
 564 auto quick copy_range
 565 auto quick copy_range
+566 auto quick locks
-- 
2.21.0

  parent reply	other threads:[~2019-09-04 12:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-27 12:35 [PATCH] generic: Add a test for basic F_SETLEASE functionality Jeff Layton
2019-08-27 20:28 ` J. Bruce Fields
2019-08-31 17:18 ` Eryu Guan
2019-09-04 12:48 ` Jeff Layton [this message]
2019-09-04 16:52   ` [PATCH v2] " Weiny, Ira
2019-09-05  0:33     ` Jeff Layton

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=20190904124849.15816-1-jlayton@kernel.org \
    --to=jlayton@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=bfields@fieldses.org \
    --cc=fstests@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.