[CRIU] [PATCH v4 4/4] zdtm: Add file lease tests
Andrei Vagin
avagin at virtuozzo.com
Mon Sep 11 21:53:48 MSK 2017
I modified the test (a patch is attached) and now criu restore fails
sometimes.
====================== Run zdtm/static/file_lease02 in h =======================
Start test
./file_lease02 --pidfile=file_lease02.pid --outfile=file_lease02.out --filename=file_lease02.test
Run criu dump
Run criu restore
=[log]=> dump/zdtm/static/file_lease02/36/1/restore.log
------------------------ grep Error ------------------------
(00.104972) 37: Receive fd for 5
(00.104977) 36: Send fd 5 to /crtools-fd-37
(00.105000) 37: Receive fd for 5
(00.105033) 37: Further fle=0x7fd5a1368ee0, pid=37
(00.105054) 37: Error (criu/file-lock.c:525): Can't set lease
: Resource temporarily unavailable
(00.105062) 37: Error (criu/file-lock.c:537): Can't set lease (fd 4)
: Resource temporarily unavailable
(00.105143) 36: Restore via sigreturn
(00.106634) 36: Error (criu/cr-restore.c:1550): 37 exited, status=1
(00.106740) Error (criu/cr-restore.c:2435): Restoring FAILED.
------------------------ ERROR OVER ------------------------
############## Test zdtm/static/file_lease02 FAIL at CRIU restore ##############
##################################### FAIL #####################################
On Sat, Sep 09, 2017 at 07:51:40PM +0300, Pavel Begunkov wrote:
> Test cases:
> 1. Basic non-breaking read/write leases.
> 2. Multiple read leases and OFDs with no lease for the same file.
> 3. Breaking leases.
>
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> ---
> test/zdtm/static/Makefile | 3 +
> test/zdtm/static/file_lease00.c | 84 ++++++++++++++++++++++
> test/zdtm/static/file_lease00.desc | 1 +
> test/zdtm/static/file_lease01.c | 88 +++++++++++++++++++++++
> test/zdtm/static/file_lease01.desc | 1 +
> test/zdtm/static/file_lease02.c | 143 +++++++++++++++++++++++++++++++++++++
> test/zdtm/static/file_lease02.desc | 1 +
> 7 files changed, 321 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 120000 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..8413f831b
> --- /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 c/r of non-breaking leases";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +char filename_rd[PATH_MAX];
> +char filename_wr[PATH_MAX];
> +
> +static void close_files(int fd1, int fd2)
> +{
> + if (fd1 >= 0)
> + close(fd1);
> + if (fd2 >= 0)
> + close(fd2);
> +
> + unlink(filename_rd);
> + unlink(filename_wr);
> +}
> +
> +static int open_files(int *fd_rd, int *fd_wr)
> +{
> + *fd_rd = open(filename_rd, O_RDONLY | O_CREAT, 0666);
> + *fd_wr = open(filename_wr, O_WRONLY | O_CREAT, 0666);
> +
> + if (*fd_rd < 0 || *fd_wr < 0) {
> + close_files(*fd_rd, *fd_wr);
> + return -1;
> + }
> + return 0;
> +}
> +
> +static int check_lease_type(int fd, int expected_type)
> +{
> + int lease_type = fcntl(fd, F_GETLEASE);
> +
> + if (lease_type != expected_type) {
> + if (lease_type < 0)
> + pr_perror("Can't acquire lease type\n");
> + else
> + pr_err("Mismatched lease type: %i\n", lease_type);
> + return -1;
> + }
> + return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int fd_rd = -1, fd_wr = -1;
> +
> + test_init(argc, argv);
> +
> + snprintf(filename_rd, sizeof(filename_rd), "%s.0", filename);
> + snprintf(filename_wr, sizeof(filename_wr), "%s.1", filename);
> +
> + if (open_files(&fd_rd, &fd_wr)) {
> + pr_err("Can't open files\n");
> + return -1;
> + }
> + if (fcntl(fd_rd, F_SETLEASE, F_RDLCK) < 0 ||
> + fcntl(fd_wr, F_SETLEASE, F_WRLCK) < 0) {
> + pr_perror("Can't set leases\n");
> + close_files(fd_rd, fd_wr);
> + return -1;
> + }
> +
> + test_daemon();
> + test_waitsig();
> +
> + if (check_lease_type(fd_rd, F_RDLCK))
> + fail("Read lease check failed\n");
> + else if (check_lease_type(fd_wr, F_WRLCK))
> + fail("Write lease check failed\n");
> + else
> + pass();
> +
> + close_files(fd_rd, fd_wr);
> + return 0;
> +}
> diff --git a/test/zdtm/static/file_lease00.desc b/test/zdtm/static/file_lease00.desc
> new file mode 100644
> index 000000000..f394d0330
> --- /dev/null
> +++ b/test/zdtm/static/file_lease00.desc
> @@ -0,0 +1 @@
> +{'feature': 'fdinfo_lock', '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..90fa74a1c
> --- /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 after c/r";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +
> +static void close_files(int fds[FD_COUNT])
> +{
> + int i;
> +
> + for (i = 0; i < FD_COUNT; ++i)
> + if (fds[i] >= 0)
> + close(fds[i]);
> + unlink(filename);
> +}
> +
> +static int open_files(int fds[FD_COUNT])
> +{
> + int i;
> +
> + for (i = 0; i < FD_COUNT; ++i) {
> + fds[i] = open(filename, O_RDONLY | O_CREAT, 0666);
> + if (fds[i] < 0) {
> + close_files(fds);
> + return -1;
> + }
> + }
> + return 0;
> +}
> +
> +static int check_lease_type(int fd, int expected_type)
> +{
> + int lease_type = fcntl(fd, F_GETLEASE);
> +
> + if (lease_type != expected_type) {
> + if (lease_type < 0)
> + pr_perror("Can't acquire lease type\n");
> + else
> + pr_err("Mismatched lease type: %i\n", lease_type);
> + return -1;
> + }
> + return 0;
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int fds[FD_COUNT];
> +
> + test_init(argc, argv);
> +
> + if (open_files(fds)) {
> + pr_err("Can't open files\n");
> + return -1;
> + }
> +
> + if (fcntl(fds[FD_LEASED1], F_SETLEASE, F_RDLCK) < 0 ||
> + fcntl(fds[FD_LEASED2], F_SETLEASE, F_RDLCK) < 0) {
> + pr_err("Can't set leases\n");
> + close_files(fds);
> + return -1;
> + }
> +
> + test_daemon();
> + test_waitsig();
> +
> + if (check_lease_type(fds[FD_LEASE_FREE], F_UNLCK))
> + fail("Unexpected lease was found (%i)\n", fds[FD_LEASE_FREE]);
> + else if (check_lease_type(fds[FD_LEASED1], F_RDLCK))
> + fail("Lease isn't set (%i)\n", fds[FD_LEASED1]);
> + else if (check_lease_type(fds[FD_LEASED2], F_RDLCK))
> + fail("Lease isn't set (%i)\n", fds[FD_LEASED2]);
> + else
> + pass();
> +
> + close_files(fds);
> + return 0;
> +}
> +
> diff --git a/test/zdtm/static/file_lease01.desc b/test/zdtm/static/file_lease01.desc
> new file mode 120000
> index 000000000..fba66d322
> --- /dev/null
> +++ b/test/zdtm/static/file_lease01.desc
> @@ -0,0 +1 @@
> +file_lease00.desc
> \ No newline at end of file
> diff --git a/test/zdtm/static/file_lease02.c b/test/zdtm/static/file_lease02.c
> new file mode 100644
> index 000000000..dc4ab0790
> --- /dev/null
> +++ b/test/zdtm/static/file_lease02.c
> @@ -0,0 +1,143 @@
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <signal.h>
> +#include <limits.h>
> +
> +#include "zdtmtst.h"
> +
> +#define FD_COUNT 3
> +#define BREAK_SIGNUM SIGIO
> +
> +const char *test_doc = "Check c/r of breaking leases";
> +const char *test_author = "Pavel Begunkov <asml.silence at gmail.com>";
> +
> +char *filename;
> +TEST_OPTION(filename, string, "file name", 1);
> +
> +char filename1[PATH_MAX];
> +char filename2[PATH_MAX];
> +char filename3[PATH_MAX];
> +
> +int expected_fd;
> +int sigaction_error = 0;
> +
> +static void break_sigaction(int signo, siginfo_t *info, void *ctx)
> +{
> + if (signo != BREAK_SIGNUM) {
> + pr_err("Unexpected signal(%i)\n", signo);
> + sigaction_error = -1;
> + } else if (info->si_fd != expected_fd) {
> + pr_err("Unexpected fd(%i)\n", info->si_fd);
> + sigaction_error = -1;
> + }
> + expected_fd = -1;
> +}
> +
> +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;
> +}
> +
> +static 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) {
> + pr_perror("Can't set exclusive lease\n");
> + goto err;
> + }
> + if (fcntl(fd, F_SETSIG, BREAK_SIGNUM) < 0) {
> + pr_perror("Can't set signum for file i/o\n");
> + goto err;
> + }
> +
> + expected_fd = fd;
> + fd_break = open(file, break_type | O_NONBLOCK);
> +
> + if (fd_break >= 0) {
> + close(fd_break);
> + pr_err("Conflicting lease not found\n");
> + goto err;
> + } else if (errno != EWOULDBLOCK) {
> + pr_perror("Can't break lease\n");
> + goto err;
> + }
> + return fd;
> +err:
> + close(fd);
> + return -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(filename1);
> + unlink(filename2);
> + unlink(filename3);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int fds[FD_COUNT];
> + int ret = -1;
> + struct sigaction act = {};
> +
> + 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);
> +
> + act.sa_sigaction = break_sigaction;
> + act.sa_flags = SA_SIGINFO;
> +
> + if (sigemptyset(&act.sa_mask) ||
> + sigaddset(&act.sa_mask, BREAK_SIGNUM) ||
> + sigaction(BREAK_SIGNUM, &act, NULL)) {
> + pr_perror("Can't set signal action\n");
> + fail();
> + 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 || sigaction_error)
> + goto done;
> +
> + test_daemon();
> + test_waitsig();
> +
> + ret = 0;
> + if (sigaction_error)
> + fail("Ghost signal\n");
> + else if (check_lease_type(fds[0], F_UNLCK) ||
> + check_lease_type(fds[1], F_RDLCK) ||
> + check_lease_type(fds[2], F_UNLCK))
> + fail("Lease type doesn't match\n");
> + else
> + pass();
> +done:
> + close_files(fds);
> + return ret;
> +}
> +
> diff --git a/test/zdtm/static/file_lease02.desc b/test/zdtm/static/file_lease02.desc
> new file mode 120000
> index 000000000..fba66d322
> --- /dev/null
> +++ b/test/zdtm/static/file_lease02.desc
> @@ -0,0 +1 @@
> +file_lease00.desc
> \ No newline at end of file
> --
> 2.11.1
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
-------------- next part --------------
diff --git a/test/zdtm/static/file_lease02.c b/test/zdtm/static/file_lease02.c
index dc4ab0790..fc8aee424 100644
--- a/test/zdtm/static/file_lease02.c
+++ b/test/zdtm/static/file_lease02.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <signal.h>
#include <limits.h>
+#include <sys/wait.h>
#include "zdtmtst.h"
@@ -100,6 +101,7 @@ int main(int argc, char **argv)
int fds[FD_COUNT];
int ret = -1;
struct sigaction act = {};
+ int pid;
test_init(argc, argv);
@@ -120,19 +122,33 @@ int main(int argc, char **argv)
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 || sigaction_error)
+ if (fds[0] < 0 || fds[1] < 0 || sigaction_error)
goto done;
+ pid = fork();
+ if (pid < 0)
+ return 1;
+ if (pid == 0) {
+ fds[2] = prepare_file(filename3, O_WRONLY, O_WRONLY);
+ if (fds[2] < 0)
+ goto done;
+ test_waitsig();
+ if (check_lease_type(fds[2], F_UNLCK))
+ return 1;
+ return 0;
+ }
+
test_daemon();
test_waitsig();
+ kill(pid, SIGTERM);
+ waitpid(pid, NULL, 0);
+
ret = 0;
if (sigaction_error)
fail("Ghost signal\n");
else if (check_lease_type(fds[0], F_UNLCK) ||
- check_lease_type(fds[1], F_RDLCK) ||
- check_lease_type(fds[2], F_UNLCK))
+ check_lease_type(fds[1], F_RDLCK))
fail("Lease type doesn't match\n");
else
pass();
More information about the CRIU
mailing list