[v3,4/4] zdtm: Add file lease tests

Submitted by Pavel Begunkov (Silence) on Sept. 7, 2017, 8:05 a.m.

Details

Message ID 20170907080529.30886-5-asml.silence@gmail.com
State New
Series "file leases support"
Headers show

Commit Message

Pavel Begunkov (Silence) Sept. 7, 2017, 8:05 a.m.
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@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

Patch hide | download patch | download mbox

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@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'}
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@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@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

Comments

Andrei Vagin Sept. 7, 2017, 3:15 p.m.
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@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@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'}

Why do you need the excl flag here? This flag is set for other lock
tests, because they read /proc/locks. I think it is not required in this
case.

Thanks

> 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@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@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@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
Pavel Begunkov (Silence) Sept. 7, 2017, 3:29 p.m.
On 07/09/17 18:15, Andrei Vagin wrote:
> 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@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@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'}
> 
> Why do you need the excl flag here? This flag is set for other lock
> tests, because they read /proc/locks. I think it is not required in this
> case.
Yeah, you are right. I'll fix it & resend patch. This one also reads
/proc/locks, however it always can match locks and OFDs, but
implementation for other locks cannot.

> 
> Thanks
> 
>> 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@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@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@openvz.org
>> https://lists.openvz.org/mailman/listinfo/criu
Andrei Vagin Sept. 7, 2017, 3:57 p.m.
On Thu, Sep 07, 2017 at 06:29:52PM +0300, Pavel Begunkov wrote:
> On 07/09/17 18:15, Andrei Vagin wrote:
> > 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@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@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'}
> > 
> > Why do you need the excl flag here? This flag is set for other lock
> > tests, because they read /proc/locks. I think it is not required in this
> > case.
> Yeah, you are right. I'll fix it & resend patch. This one also reads
> /proc/locks, however it always can match locks and OFDs, but
> implementation for other locks cannot.

I can't find a place where it read /proc/locks, but it it does, pls
rewrite it to read /proc/pid/fd/fdinfo

/proc/locks can show one lock twice and the pid field for some locks may
be incorrect. It was a reason why we added information about locks in
fdinfo.
> 
> > 
> > Thanks
> > 
> >> 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@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@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@openvz.org
> >> https://lists.openvz.org/mailman/listinfo/criu
> 
> -- 
> Yours sincerely,
> Pavel
>
Pavel Begunkov (Silence) Sept. 7, 2017, 4:10 p.m.
On 07/09/17 18:57, Andrei Vagin wrote:
> On Thu, Sep 07, 2017 at 06:29:52PM +0300, Pavel Begunkov wrote:
>> On 07/09/17 18:15, Andrei Vagin wrote:
>>> 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@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@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'}
>>>
>>> Why do you need the excl flag here? This flag is set for other lock
>>> tests, because they read /proc/locks. I think it is not required in this
>>> case.
>> Yeah, you are right. I'll fix it & resend patch. This one also reads
>> /proc/locks, however it always can match locks and OFDs, but
>> implementation for other locks cannot.
> 
> I can't find a place where it read /proc/locks, but it it does, pls
> rewrite it to read /proc/pid/fd/fdinfo
It based on CRIU infrastructure for c/r file locks. I didn't change
parsing logic. It uses /proc/pid/fd/fdinfo if it's possible or reads
/proc/locks otherwise (somewhere in proc_parse.c).

3rd patch of the patchset is intended to support the case of /proc/locks
(see *note_file_lock* function).

> 
> /proc/locks can show one lock twice and the pid field for some locks may
> be incorrect. It was a reason why we added information about locks in
> fdinfo.
>>
>>>
>>> Thanks
>>>
>>>> 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@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@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@openvz.org
>>>> https://lists.openvz.org/mailman/listinfo/criu
>>
>> -- 
>> Yours sincerely,
>> Pavel
>>
> 
> 
>
Andrei Vagin Sept. 7, 2017, 4:34 p.m.
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@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@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@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@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@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
Pavel Begunkov (Silence) Sept. 7, 2017, 4:47 p.m.
Hmm, ok. Then could you say, why other file_lock* tests are excluded but
not require this feature? They have the same behaviour about procfs
usage. Maybe, their .desc also should be modified in such way?

On 07/09/17 19:34, Andrei Vagin wrote:
> 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@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@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@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@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@openvz.org
>> https://lists.openvz.org/mailman/listinfo/criu
Andrei Vagin Sept. 7, 2017, 5:33 p.m.
On Thu, Sep 07, 2017 at 07:47:48PM +0300, Pavel Begunkov wrote:
> Hmm, ok. Then could you say, why other file_lock* tests are excluded but
> not require this feature? They have the same behaviour about procfs
> usage. Maybe, their .desc also should be modified in such way?

because they can work without locks in fdinfo

> 
> On 07/09/17 19:34, Andrei Vagin wrote:
> > 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@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@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@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@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@openvz.org
> >> https://lists.openvz.org/mailman/listinfo/criu
> 
> -- 
> Yours sincerely,
> Pavel
>
Andrei Vagin Sept. 7, 2017, 5:35 p.m.
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@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@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'}
> 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@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@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) {

You need to install a handler and check that you don't get extra signals
during C/R.

> +		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@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu