Skip to content

Commit 33dca79

Browse files
committed
zdtm: add file_lease05 test for broken read lease restore
Add a test that exercises the broken read lease restore path. The test: 1. Opens a file O_RDONLY and takes a read lease (F_RDLCK). 2. Triggers the breaking sequence by attempting a conflicting O_WRONLY | O_NONBLOCK open (which returns EWOULDBLOCK). 3. Forks a child to verify post-restore lease state. 4. Calls test_daemon() / test_waitsig() to go through C/R. 5. After restore, the child verifies that the lease type is F_UNLCK (the expected target type for a broken read lease), confirming that the breaking sequence was correctly re-established. Without the preceding fix, restore_lease_prebreaking_state() would set a write lease (F_WRLCK) instead of a read lease on the read-only fd, causing either a restore failure (EACCES) or a wrong lease type post-restore. This test fails without the fix and passes with it. Signed-off-by: Andrei Vagin <avagin@google.com>
1 parent 64c8d4a commit 33dca79

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

test/zdtm/static/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ TST_FILE = \
366366
file_lease02 \
367367
file_lease03 \
368368
file_lease04 \
369+
file_lease05 \
369370
file_locks00 \
370371
file_locks00_fail \
371372
file_locks01 \

test/zdtm/static/file_lease05.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <fcntl.h>
2+
#include <limits.h>
3+
#include <signal.h>
4+
#include <stdio.h>
5+
#include <sys/wait.h>
6+
7+
#include "zdtmtst.h"
8+
9+
const char *test_doc = "Check broken read-lease is restored with correct type";
10+
const char *test_author = "Andrei Vagin <avagin@gmail.com>";
11+
12+
char *filename;
13+
TEST_OPTION(filename, string, "file name", 1);
14+
15+
static void break_sigaction(int signo, siginfo_t *info, void *ctx)
16+
{
17+
}
18+
19+
int main(int argc, char **argv)
20+
{
21+
struct sigaction act = {};
22+
int fd;
23+
24+
test_init(argc, argv);
25+
26+
act.sa_sigaction = break_sigaction;
27+
act.sa_flags = SA_SIGINFO | SA_RESTART;
28+
if (sigaction(SIGIO, &act, NULL)) {
29+
pr_perror("Can't set signal action");
30+
return 1;
31+
}
32+
33+
fd = open(filename, O_RDONLY | O_CREAT, 0666);
34+
if (fd < 0) {
35+
pr_perror("Can't open file");
36+
return 1;
37+
}
38+
39+
if (fcntl(fd, F_SETLEASE, F_RDLCK) < 0) {
40+
pr_perror("Can't set read lease");
41+
return 1;
42+
}
43+
44+
if (fcntl(fd, F_SETSIG, SIGIO) < 0) {
45+
pr_perror("Can't set lease signal");
46+
return 1;
47+
}
48+
49+
{
50+
int fd_break = open(filename, O_WRONLY | O_NONBLOCK);
51+
if (fd_break >= 0) {
52+
close(fd_break);
53+
pr_err("Conflicting lease not found\n");
54+
return 1;
55+
} else if (errno != EWOULDBLOCK) {
56+
pr_perror("Can't break lease");
57+
return 1;
58+
}
59+
}
60+
61+
test_daemon();
62+
test_waitsig();
63+
64+
{
65+
int fd_check = open(filename, O_RDONLY | O_NONBLOCK);
66+
if (fd_check >= 0) {
67+
close(fd_check);
68+
} else if (errno == EWOULDBLOCK) {
69+
fail("Unexpected lease has been found");
70+
return 1;
71+
} else {
72+
pr_perror("unexpected error");
73+
return 1;
74+
}
75+
}
76+
{
77+
int fd_break = open(filename, O_WRONLY | O_NONBLOCK);
78+
if (fd_break >= 0) {
79+
close(fd_break);
80+
fail("Conflicting lease not found");
81+
return 1;
82+
} else if (errno != EWOULDBLOCK) {
83+
pr_perror("unexpected error");
84+
return 1;
85+
}
86+
}
87+
pass();
88+
return 0;
89+
}

test/zdtm/static/file_lease05.desc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{'feature': 'fdinfo_lock', 'opts': '--file-locks'}

0 commit comments

Comments
 (0)