All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Jeff Layton <jlayton@kernel.org>
Cc: fstests@vger.kernel.org, amir73il@gmail.com
Subject: Re: [PATCH] generic: Add a test for basic F_SETLEASE functionality
Date: Tue, 27 Aug 2019 16:28:17 -0400	[thread overview]
Message-ID: <20190827202817.GA13198@fieldses.org> (raw)
In-Reply-To: <20190827123537.18794-1-jlayton@kernel.org>

On Tue, Aug 27, 2019 at 08:35:37AM -0400, Jeff Layton wrote:
> 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.

I've been using tests of my own for this.  Looks like your tests cover
the same cases as mine with less code.  So, looks good to me, thanks!

--b.

> 
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  src/Makefile          |   2 +-
>  src/t_setlease.c      | 157 ++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/566     |  54 +++++++++++++++
>  tests/generic/566.out |   1 +
>  tests/generic/group   |   1 +
>  5 files changed, 214 insertions(+), 1 deletion(-)
>  create mode 100644 src/t_setlease.c
>  create mode 100755 tests/generic/566
>  create mode 100644 tests/generic/566.out
> 
> 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..81d46b6a6cd4
> --- /dev/null
> +++ b/src/t_setlease.c
> @@ -0,0 +1,157 @@
> +/*
> + * 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);
> +		int 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);
> +	}
> +
> +	fcntl(fd, F_SETLEASE, F_UNLCK);
> +	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..abf4f6dd743a
> --- /dev/null
> +++ b/tests/generic/566
> @@ -0,0 +1,54 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2019 YOUR NAME HERE.  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
> +
> +# if error
> +testfile=$TEST_DIR/t_setlease-testfile
> +$here/src/t_setlease $testfile
> +
> +# optional stuff if your test has verbose output to help resolve problems
> +#echo
> +#echo "If failure, check $seqres.full (this) and $seqres.full.ok (reference)"
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/566.out b/tests/generic/566.out
> new file mode 100644
> index 000000000000..9cd099b9d317
> --- /dev/null
> +++ b/tests/generic/566.out
> @@ -0,0 +1 @@
> +QA output created by 566
> 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

  reply	other threads:[~2019-08-27 20:28 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 [this message]
2019-08-31 17:18 ` Eryu Guan
2019-09-04 12:48 ` [PATCH v2] " Jeff Layton
2019-09-04 16:52   ` 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=20190827202817.GA13198@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=amir73il@gmail.com \
    --cc=fstests@vger.kernel.org \
    --cc=jlayton@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.