[CRIU] [PATCH v3 4/4] zdtm: Add file lease tests

Andrei Vagin avagin at virtuozzo.com
Thu Sep 7 19:34:57 MSK 2017


On Thu, Sep 07, 2017 at 11:05:29AM +0300, Pavel Begunkov wrote:
> Test cases:
> 1. Basic non-breaking read/write leases.
> 2. Multiple read leases and OFDs with no lease for the same file.
> 3. Breaking leases.
> 
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> ---
>  test/zdtm/static/Makefile          |   3 +
>  test/zdtm/static/file_lease00.c    |  84 +++++++++++++++++++++++++++
>  test/zdtm/static/file_lease00.desc |   1 +
>  test/zdtm/static/file_lease01.c    |  88 ++++++++++++++++++++++++++++
>  test/zdtm/static/file_lease01.desc |   1 +
>  test/zdtm/static/file_lease02.c    | 114 +++++++++++++++++++++++++++++++++++++
>  test/zdtm/static/file_lease02.desc |   1 +
>  7 files changed, 292 insertions(+)
>  create mode 100644 test/zdtm/static/file_lease00.c
>  create mode 100644 test/zdtm/static/file_lease00.desc
>  create mode 100644 test/zdtm/static/file_lease01.c
>  create mode 100644 test/zdtm/static/file_lease01.desc
>  create mode 100644 test/zdtm/static/file_lease02.c
>  create mode 120000 test/zdtm/static/file_lease02.desc
> 
> diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
> index 1e4a57545..7987e34b5 100644
> --- a/test/zdtm/static/Makefile
> +++ b/test/zdtm/static/Makefile
> @@ -221,6 +221,9 @@ TST_FILE	=				\
>  		sockets00			\
>  		sockets03			\
>  		sockets_dgram			\
> +		file_lease00			\
> +		file_lease01			\
> +		file_lease02			\
>  		file_locks00			\
>  		file_locks01			\
>  		file_locks02			\
> diff --git a/test/zdtm/static/file_lease00.c b/test/zdtm/static/file_lease00.c
> new file mode 100644
> index 000000000..2c7c876ee
> --- /dev/null
> +++ b/test/zdtm/static/file_lease00.c
> @@ -0,0 +1,84 @@
> +#include <fcntl.h>
> +#include <limits.h>
> +#include <stdio.h>
> +
> +#include "zdtmtst.h"
> +
> +const char *test_doc = "Check that non-breaking leases are restored";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +char filename_rd[PATH_MAX];
> +char filename_wr[PATH_MAX];
> +
> +static void close_files(int fd1, int fd2)
> +{
> +	if (fd1 >= 0)
> +		close(fd1);
> +	if (fd2 >= 0)
> +		close(fd2);
> +
> +	unlink(filename_rd);
> +	unlink(filename_wr);
> +}
> +
> +static int open_files(int *fd_rd, int *fd_wr)
> +{
> +	*fd_rd = open(filename_rd, O_RDONLY | O_CREAT, 0666);
> +	*fd_wr = open(filename_wr, O_WRONLY | O_CREAT, 0666);
> +
> +	if (*fd_rd < 0 || *fd_wr < 0) {
> +		close_files(*fd_rd, *fd_wr);
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +static int check_lease_type(int fd, int expected_type)
> +{
> +	int lease_type = fcntl(fd, F_GETLEASE);
> +
> +	if (lease_type != expected_type) {
> +		if (lease_type < 0)
> +			pr_perror("Can't acquire lease type\n");
> +		else
> +			pr_err("Mismatched lease type: %i\n", lease_type);
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int fd_rd = -1, fd_wr = -1;
> +
> +	test_init(argc, argv);
> +
> +	snprintf(filename_rd, sizeof(filename_rd), "%s.0", filename);
> +	snprintf(filename_wr, sizeof(filename_wr), "%s.1", filename);
> +
> +	if (open_files(&fd_rd, &fd_wr)) {
> +		pr_err("Can't open files\n");
> +		return -1;
> +	}
> +	if (fcntl(fd_rd, F_SETLEASE, F_RDLCK) < 0 ||
> +		fcntl(fd_wr, F_SETLEASE, F_WRLCK) < 0) {
> +		pr_perror("Can't set leases\n");
> +		close_files(fd_rd, fd_wr);
> +		return -1;
> +	}
> +
> +	test_daemon();
> +	test_waitsig();
> +
> +	if (check_lease_type(fd_rd, F_RDLCK))
> +		fail("Read lease check failed\n");
> +	else if (check_lease_type(fd_wr, F_WRLCK))
> +		fail("Write lease check failed\n");
> +	else
> +		pass();
> +
> +	close_files(fd_rd, fd_wr);
> +	return 0;
> +}
> diff --git a/test/zdtm/static/file_lease00.desc b/test/zdtm/static/file_lease00.desc
> new file mode 100644
> index 000000000..80cd04e28
> --- /dev/null
> +++ b/test/zdtm/static/file_lease00.desc
> @@ -0,0 +1 @@
> +{'flags': 'excl', 'opts': '--file-locks'}

And you probably have to add the fdinfo_lock feature for these tests

'feature': 'fdinfo_lock'

> diff --git a/test/zdtm/static/file_lease01.c b/test/zdtm/static/file_lease01.c
> new file mode 100644
> index 000000000..3ff20fb05
> --- /dev/null
> +++ b/test/zdtm/static/file_lease01.c
> @@ -0,0 +1,88 @@
> +#include <fcntl.h>
> +#include <stdio.h>
> +
> +#include "zdtmtst.h"
> +
> +#define FD_COUNT 3
> +#define FD_LEASED1 0
> +#define FD_LEASED2 2
> +#define FD_LEASE_FREE 1
> +
> +const char *test_doc = "Check that extra leases are not set";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +
> +static void close_files(int fds[FD_COUNT])
> +{
> +	int i;
> +
> +	for (i = 0; i < FD_COUNT; ++i)
> +		if (fds[i] >= 0)
> +			close(fds[i]);
> +	unlink(filename);
> +}
> +
> +static int open_files(int fds[FD_COUNT])
> +{
> +	int i;
> +
> +	for (i = 0; i < FD_COUNT; ++i) {
> +		fds[i] = open(filename, O_RDONLY | O_CREAT, 0666);
> +		if (fds[i] < 0) {
> +			close_files(fds);
> +			return -1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int check_lease_type(int fd, int expected_type)
> +{
> +	int lease_type = fcntl(fd, F_GETLEASE);
> +
> +	if (lease_type != expected_type) {
> +		if (lease_type < 0)
> +			pr_perror("Can't acquire lease type\n");
> +		else
> +			pr_err("Mismatched lease type: %i\n", lease_type);
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int fds[FD_COUNT];
> +
> +	test_init(argc, argv);
> +
> +	if (open_files(fds)) {
> +		pr_err("Can't open files\n");
> +		return -1;
> +	}
> +
> +	if (fcntl(fds[FD_LEASED1], F_SETLEASE, F_RDLCK) < 0 ||
> +		fcntl(fds[FD_LEASED2], F_SETLEASE, F_RDLCK) < 0) {
> +		pr_err("Can't set leases\n");
> +		close_files(fds);
> +		return -1;
> +	}
> +
> +	test_daemon();
> +	test_waitsig();
> +
> +	if (check_lease_type(fds[FD_LEASE_FREE], F_UNLCK))
> +		fail("Unexpected lease was found (%i)\n", fds[FD_LEASE_FREE]);
> +	else if (check_lease_type(fds[FD_LEASED1], F_RDLCK))
> +		fail("Lease isn't set (%i)\n", fds[FD_LEASED1]);
> +	else if (check_lease_type(fds[FD_LEASED2], F_RDLCK))
> +		fail("Lease isn't set (%i)\n", fds[FD_LEASED2]);
> +	else
> +		pass();
> +
> +	close_files(fds);
> +	return 0;
> +}
> +
> diff --git a/test/zdtm/static/file_lease01.desc b/test/zdtm/static/file_lease01.desc
> new file mode 100644
> index 000000000..80cd04e28
> --- /dev/null
> +++ b/test/zdtm/static/file_lease01.desc
> @@ -0,0 +1 @@
> +{'flags': 'excl', 'opts': '--file-locks'}
> diff --git a/test/zdtm/static/file_lease02.c b/test/zdtm/static/file_lease02.c
> new file mode 100644
> index 000000000..404a75f72
> --- /dev/null
> +++ b/test/zdtm/static/file_lease02.c
> @@ -0,0 +1,114 @@
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <signal.h>
> +#include <limits.h>
> +
> +#include "zdtmtst.h"
> +
> +#define FD_COUNT 3
> +
> +const char *test_doc = "Check that breaking leases are restored";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +
> +char filename1[PATH_MAX];
> +char filename2[PATH_MAX];
> +char filename3[PATH_MAX];
> +
> +static int check_lease_type(int fd, int expected_type)
> +{
> +	int lease_type = fcntl(fd, F_GETLEASE);
> +
> +	if (lease_type != expected_type) {
> +		if (lease_type < 0)
> +			pr_perror("Can't acquire lease type\n");
> +		else
> +			pr_err("Mismatched lease type: %i\n", lease_type);
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +int prepare_file(char* file, int file_type, int break_type)
> +{
> +	int fd, fd_break;
> +	int lease_type = (file_type == O_RDONLY) ? F_RDLCK : F_WRLCK;
> +
> +	fd = open(file, file_type | O_CREAT, 0666);
> +	if (fd < 0) {
> +		pr_perror("Can't open file (type %i)\n", file_type);
> +		return fd;
> +	}
> +
> +	if (fcntl(fd, F_SETLEASE, lease_type) < 0) {
> +		close(fd);
> +		pr_perror("Can't set exclusive lease\n");
> +		return -1;
> +	}
> +
> +	fd_break = open(file, break_type | O_NONBLOCK);
> +	if (fd_break >= 0) {
> +		close(fd);
> +		close(fd_break);
> +		pr_err("Conflicting lease not found\n");
> +		return -1;
> +	} else if (errno != EWOULDBLOCK) {
> +		close(fd);
> +		pr_perror("Can't break lease\n");
> +		return -1;
> +	}
> +	return fd;
> +}
> +
> +void close_files(int fds[FD_COUNT])
> +{
> +	int i;
> +	for (i = 0; i < FD_COUNT; ++i)
> +		if (fds[i] >= 0)
> +			close(fds[i]);
> +
> +	unlink(filename1);
> +	unlink(filename2);
> +	unlink(filename3);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int fds[FD_COUNT];
> +	int ret = -1;
> +
> +	test_init(argc, argv);
> +
> +	snprintf(filename1, sizeof(filename1), "%s.0", filename);
> +	snprintf(filename2, sizeof(filename2), "%s.1", filename);
> +	snprintf(filename3, sizeof(filename3), "%s.2", filename);
> +
> +	if (signal(SIGIO, SIG_IGN) == SIG_ERR) {
> +		pr_err("Can't silent SIGIO\n");
> +		return -1;
> +	}
> +
> +	fds[0] = prepare_file(filename1, O_RDONLY, O_WRONLY);
> +	fds[1] = prepare_file(filename2, O_WRONLY, O_RDONLY);
> +	fds[2] = prepare_file(filename3, O_WRONLY, O_WRONLY);
> +	if (fds[0] < 0 || fds[1] < 0 || fds[2] < 0)
> +		goto done;
> +
> +	test_daemon();
> +	test_waitsig();
> +
> +	ret = 0;
> +	if (check_lease_type(fds[0], F_UNLCK) ||
> +		check_lease_type(fds[1], F_RDLCK) ||
> +		check_lease_type(fds[2], F_UNLCK))
> +		fail("Lease type doesn't match\n");
> +	else
> +		pass();
> +
> +done:
> +	close_files(fds);
> +	return ret;
> +}
> +
> diff --git a/test/zdtm/static/file_lease02.desc b/test/zdtm/static/file_lease02.desc
> new file mode 120000
> index 000000000..fba66d322
> --- /dev/null
> +++ b/test/zdtm/static/file_lease02.desc
> @@ -0,0 +1 @@
> +file_lease00.desc
> \ No newline at end of file
> -- 
> 2.11.1
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list