xref: /xnu-11417.140.69/tests/file_leases.c (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
1*43a90889SApple OSS Distributions /* compile: xcrun -sdk macosx.internal clang -ldarwintest -o test_file_leases file_leases.c -g -Weverything */
2*43a90889SApple OSS Distributions 
3*43a90889SApple OSS Distributions #include <darwintest.h>
4*43a90889SApple OSS Distributions #include <darwintest_utils.h>
5*43a90889SApple OSS Distributions #include <darwintest_multiprocess.h>
6*43a90889SApple OSS Distributions #include <copyfile.h>
7*43a90889SApple OSS Distributions #include <errno.h>
8*43a90889SApple OSS Distributions #include <fcntl.h>
9*43a90889SApple OSS Distributions #include <stdint.h>
10*43a90889SApple OSS Distributions #include <stdlib.h>
11*43a90889SApple OSS Distributions #include <unistd.h>
12*43a90889SApple OSS Distributions #include <sys/clonefile.h>
13*43a90889SApple OSS Distributions #include <sys/event.h>
14*43a90889SApple OSS Distributions #include <sys/resource.h>
15*43a90889SApple OSS Distributions #include <sys/sysctl.h>
16*43a90889SApple OSS Distributions #include <sys/xattr.h>
17*43a90889SApple OSS Distributions 
18*43a90889SApple OSS Distributions #include "test_utils.h"
19*43a90889SApple OSS Distributions 
20*43a90889SApple OSS Distributions 
21*43a90889SApple OSS Distributions T_GLOBAL_META(
22*43a90889SApple OSS Distributions 	T_META_NAMESPACE("xnu.vfs.lease"),
23*43a90889SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
24*43a90889SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("vfs"),
25*43a90889SApple OSS Distributions 	T_META_CHECK_LEAKS(false),
26*43a90889SApple OSS Distributions 	T_META_TAG_VM_PREFERRED);
27*43a90889SApple OSS Distributions 
28*43a90889SApple OSS Distributions #define TEST_LEASE_DIR  "lease_dir"
29*43a90889SApple OSS Distributions #define TEST_LEASE_FILE "lease_file"
30*43a90889SApple OSS Distributions 
31*43a90889SApple OSS Distributions static char g_testfile[MAXPATHLEN];
32*43a90889SApple OSS Distributions static char g_testdir[MAXPATHLEN];
33*43a90889SApple OSS Distributions 
34*43a90889SApple OSS Distributions /*
35*43a90889SApple OSS Distributions  * This unit-test validates the behavior of file leasing (read and write leases)
36*43a90889SApple OSS Distributions  * by utilizing the file leasing API (fcntl's F_SETLEASE and F_GETLEASE
37*43a90889SApple OSS Distributions  * commands) provided by VFS.
38*43a90889SApple OSS Distributions  */
39*43a90889SApple OSS Distributions 
40*43a90889SApple OSS Distributions 
41*43a90889SApple OSS Distributions static void
exit_cleanup(void)42*43a90889SApple OSS Distributions exit_cleanup(void)
43*43a90889SApple OSS Distributions {
44*43a90889SApple OSS Distributions 	uint32_t val, new_val;
45*43a90889SApple OSS Distributions 	size_t val_len, new_val_len;
46*43a90889SApple OSS Distributions 
47*43a90889SApple OSS Distributions 	(void)remove(g_testfile);
48*43a90889SApple OSS Distributions 	(void)rmdir(g_testdir);
49*43a90889SApple OSS Distributions 
50*43a90889SApple OSS Distributions 	new_val = 60;
51*43a90889SApple OSS Distributions 	new_val_len = val_len = sizeof(uint32_t);
52*43a90889SApple OSS Distributions 	(void)sysctlbyname("vfs.lease.break_timeout", &val, &val_len,
53*43a90889SApple OSS Distributions 	    (void *)&new_val, new_val_len);
54*43a90889SApple OSS Distributions }
55*43a90889SApple OSS Distributions 
56*43a90889SApple OSS Distributions 
57*43a90889SApple OSS Distributions static void
create_test_file(void)58*43a90889SApple OSS Distributions create_test_file(void)
59*43a90889SApple OSS Distributions {
60*43a90889SApple OSS Distributions 	const char *tmpdir = dt_tmpdir();
61*43a90889SApple OSS Distributions 	int fd;
62*43a90889SApple OSS Distributions 
63*43a90889SApple OSS Distributions 	T_SETUPBEGIN;
64*43a90889SApple OSS Distributions 
65*43a90889SApple OSS Distributions 	/*
66*43a90889SApple OSS Distributions 	 * Make sure dataless file manipulation is enabled for this
67*43a90889SApple OSS Distributions 	 * process (children will inherit).
68*43a90889SApple OSS Distributions 	 *
69*43a90889SApple OSS Distributions 	 * See kpi_vfs.c:vfs_context_can_break_leases().
70*43a90889SApple OSS Distributions 	 */
71*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(
72*43a90889SApple OSS Distributions 		setiopolicy_np(IOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES,
73*43a90889SApple OSS Distributions 		IOPOL_SCOPE_PROCESS, IOPOL_MATERIALIZE_DATALESS_FILES_ON),
74*43a90889SApple OSS Distributions 		"Setup: ensuring dataless file materialization is enabled");
75*43a90889SApple OSS Distributions 
76*43a90889SApple OSS Distributions 	atexit(exit_cleanup);
77*43a90889SApple OSS Distributions 
78*43a90889SApple OSS Distributions 	snprintf(g_testdir, MAXPATHLEN, "%s/%s", tmpdir, TEST_LEASE_DIR);
79*43a90889SApple OSS Distributions 
80*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(mkdir(g_testdir, 0777),
81*43a90889SApple OSS Distributions 	    "Setup: creating test dir: %s", g_testdir);
82*43a90889SApple OSS Distributions 
83*43a90889SApple OSS Distributions 	snprintf(g_testfile, MAXPATHLEN, "%s/%s", g_testdir, TEST_LEASE_FILE);
84*43a90889SApple OSS Distributions 
85*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
86*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_CREAT | O_RDWR, 0666);
87*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Create test fi1e: %s", g_testfile);
88*43a90889SApple OSS Distributions 
89*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", TEST_LEASE_FILE);
90*43a90889SApple OSS Distributions 
91*43a90889SApple OSS Distributions 	T_SETUPEND;
92*43a90889SApple OSS Distributions }
93*43a90889SApple OSS Distributions 
94*43a90889SApple OSS Distributions #define HELPER_TIMEOUT_SECS     60
95*43a90889SApple OSS Distributions #define MAX_HELPERS             10
96*43a90889SApple OSS Distributions 
97*43a90889SApple OSS Distributions static void __attribute__((noreturn))
run_helpers(const char ** helper_test_names,int num_helpers)98*43a90889SApple OSS Distributions run_helpers(const char **helper_test_names, int num_helpers)
99*43a90889SApple OSS Distributions {
100*43a90889SApple OSS Distributions 	dt_helper_t helpers[MAX_HELPERS];
101*43a90889SApple OSS Distributions 	char *args[] = {g_testfile, g_testdir, NULL};
102*43a90889SApple OSS Distributions 	int i;
103*43a90889SApple OSS Distributions 
104*43a90889SApple OSS Distributions 	T_QUIET;
105*43a90889SApple OSS Distributions 	T_ASSERT_LE(num_helpers, MAX_HELPERS, "too many helpers");
106*43a90889SApple OSS Distributions 
107*43a90889SApple OSS Distributions 	for (i = 0; i < num_helpers; i++) {
108*43a90889SApple OSS Distributions 		helpers[i] = dt_child_helper_args(helper_test_names[i], args);
109*43a90889SApple OSS Distributions 	}
110*43a90889SApple OSS Distributions 	dt_run_helpers(helpers, (size_t)num_helpers, HELPER_TIMEOUT_SECS);
111*43a90889SApple OSS Distributions }
112*43a90889SApple OSS Distributions 
113*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_acquire_read_lease_succeed, "Open file in O_RDONLY mode and acquire read lease succeeded")
114*43a90889SApple OSS Distributions {
115*43a90889SApple OSS Distributions 	char *testfile = argv[0];
116*43a90889SApple OSS Distributions 	int err, fd;
117*43a90889SApple OSS Distributions 
118*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
119*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
120*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
121*43a90889SApple OSS Distributions 
122*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
123*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
124*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read lease: %s", testfile);
125*43a90889SApple OSS Distributions 
126*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
127*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
128*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_RDLCK, "Retrieve lease: %s", testfile);
129*43a90889SApple OSS Distributions 
130*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", testfile);
131*43a90889SApple OSS Distributions }
132*43a90889SApple OSS Distributions 
133*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_acquire_read_lease_EAGAIN, "Open file in O_RDONLY mode and acquire read lease failed with EAGAIN")
134*43a90889SApple OSS Distributions {
135*43a90889SApple OSS Distributions 	char *testfile = argv[0];
136*43a90889SApple OSS Distributions 	int err, fd;
137*43a90889SApple OSS Distributions 
138*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
139*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
140*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
141*43a90889SApple OSS Distributions 
142*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
143*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
144*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EAGAIN), "Acquire read lease: %s",
145*43a90889SApple OSS Distributions 	    testfile);
146*43a90889SApple OSS Distributions 
147*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", testfile);
148*43a90889SApple OSS Distributions }
149*43a90889SApple OSS Distributions 
150*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdwr_acquire_write_lease_EAGAIN, "Open file in O_RDWR mode and acquire write lease failed with EAGAIN")
151*43a90889SApple OSS Distributions {
152*43a90889SApple OSS Distributions 	char *testfile = argv[0];
153*43a90889SApple OSS Distributions 	int err, fd;
154*43a90889SApple OSS Distributions 
155*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
156*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDWR, 0666);
157*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDWR: %s", testfile);
158*43a90889SApple OSS Distributions 
159*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
160*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
161*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EAGAIN), "Acquire write lease: %s",
162*43a90889SApple OSS Distributions 	    testfile);
163*43a90889SApple OSS Distributions 
164*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", testfile);
165*43a90889SApple OSS Distributions }
166*43a90889SApple OSS Distributions 
167*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_read_lease_release, "Open file in O_RDONLY mode, acquire read lease, and release lease upon NOTE_LEASE_RELEASE event")
168*43a90889SApple OSS Distributions {
169*43a90889SApple OSS Distributions 	struct kevent lease_kevent;
170*43a90889SApple OSS Distributions 	struct timespec kevent_timeout;
171*43a90889SApple OSS Distributions 	char *testfile = argv[0];
172*43a90889SApple OSS Distributions 	int err, fd, kq;
173*43a90889SApple OSS Distributions 
174*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
175*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
176*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
177*43a90889SApple OSS Distributions 
178*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
179*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
180*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read lease: %s", testfile);
181*43a90889SApple OSS Distributions 
182*43a90889SApple OSS Distributions 	kq = kqueue();
183*43a90889SApple OSS Distributions 	T_ASSERT_NE(kq, -1, "Create kqueue");
184*43a90889SApple OSS Distributions 
185*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
186*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
187*43a90889SApple OSS Distributions 	    (NOTE_LEASE_DOWNGRADE | NOTE_LEASE_RELEASE), 0, (void *)testfile);
188*43a90889SApple OSS Distributions 	err = kevent(kq, &lease_kevent, 1, NULL, 0, &kevent_timeout);
189*43a90889SApple OSS Distributions 	T_ASSERT_GE(err, 0, "Register lease event on kq: %d", kq);
190*43a90889SApple OSS Distributions 
191*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = 60;
192*43a90889SApple OSS Distributions 	kevent_timeout.tv_nsec = 0;
193*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
194*43a90889SApple OSS Distributions 
195*43a90889SApple OSS Distributions 	err = kevent(kq, NULL, 0, &lease_kevent, 1, &kevent_timeout);
196*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Listen for lease event on kq: %d", kq);
197*43a90889SApple OSS Distributions 
198*43a90889SApple OSS Distributions 	if (err > 0) {
199*43a90889SApple OSS Distributions 		T_ASSERT_EQ(lease_kevent.fflags, NOTE_LEASE_RELEASE,
200*43a90889SApple OSS Distributions 		    "Got lease event 0x%x", lease_kevent.fflags);
201*43a90889SApple OSS Distributions 
202*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
203*43a90889SApple OSS Distributions 		err = fcntl(fd, F_SETLEASE, F_UNLCK);
204*43a90889SApple OSS Distributions 		T_ASSERT_NE(err, -1, "Release lease: %s", testfile);
205*43a90889SApple OSS Distributions 	} else {
206*43a90889SApple OSS Distributions 		T_FAIL("Timedout listening for lease event on kq: %d", kq);
207*43a90889SApple OSS Distributions 	}
208*43a90889SApple OSS Distributions }
209*43a90889SApple OSS Distributions 
210*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_write_lease_downgrade, "Open file in O_RDONLY mode, acquire a write lease, and downgrade lease upon NOTE_LEASE_DOWNGRADE event")
211*43a90889SApple OSS Distributions {
212*43a90889SApple OSS Distributions 	struct kevent lease_kevent;
213*43a90889SApple OSS Distributions 	struct timespec kevent_timeout;
214*43a90889SApple OSS Distributions 	char *testfile = argv[0];
215*43a90889SApple OSS Distributions 	int err, fd, kq;
216*43a90889SApple OSS Distributions 
217*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
218*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
219*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
220*43a90889SApple OSS Distributions 
221*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
222*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
223*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire write lease: %s", testfile);
224*43a90889SApple OSS Distributions 
225*43a90889SApple OSS Distributions 	kq = kqueue();
226*43a90889SApple OSS Distributions 	T_ASSERT_NE(kq, -1, "Create kqueue");
227*43a90889SApple OSS Distributions 
228*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
229*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
230*43a90889SApple OSS Distributions 	    (NOTE_LEASE_DOWNGRADE | NOTE_LEASE_RELEASE), 0, (void *)testfile);
231*43a90889SApple OSS Distributions 	err = kevent(kq, &lease_kevent, 1, NULL, 0, &kevent_timeout);
232*43a90889SApple OSS Distributions 	T_ASSERT_GE(err, 0, "Register lease event on kq: %d", kq);
233*43a90889SApple OSS Distributions 
234*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = 60;
235*43a90889SApple OSS Distributions 	kevent_timeout.tv_nsec = 0;
236*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
237*43a90889SApple OSS Distributions 
238*43a90889SApple OSS Distributions 	err = kevent(kq, NULL, 0, &lease_kevent, 1, &kevent_timeout);
239*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Listen for lease event on kq: %d", kq);
240*43a90889SApple OSS Distributions 
241*43a90889SApple OSS Distributions 	if (err > 0) {
242*43a90889SApple OSS Distributions 		T_ASSERT_EQ(lease_kevent.fflags, NOTE_LEASE_DOWNGRADE,
243*43a90889SApple OSS Distributions 		    "Got lease event 0x%x", lease_kevent.fflags);
244*43a90889SApple OSS Distributions 
245*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
246*43a90889SApple OSS Distributions 		err = fcntl(fd, F_SETLEASE, F_RDLCK);
247*43a90889SApple OSS Distributions 		T_ASSERT_NE(err, -1, "Downgrade to read lease: %s", testfile);
248*43a90889SApple OSS Distributions 	} else {
249*43a90889SApple OSS Distributions 		T_FAIL("Timedout listening for lease event on kq: %d", kq);
250*43a90889SApple OSS Distributions 	}
251*43a90889SApple OSS Distributions }
252*43a90889SApple OSS Distributions 
253*43a90889SApple OSS Distributions T_HELPER_DECL(open_rw_write_lease_downgrade, "Open file multiple times in O_RDWR mode, acquire a write lease, and downgrade lease upon NOTE_LEASE_DOWNGRADE event")
254*43a90889SApple OSS Distributions {
255*43a90889SApple OSS Distributions 	struct kevent lease_kevent;
256*43a90889SApple OSS Distributions 	struct timespec kevent_timeout;
257*43a90889SApple OSS Distributions 	char *testfile = argv[0];
258*43a90889SApple OSS Distributions 	int err, rw_fd1, rw_fd2, fd, kq;
259*43a90889SApple OSS Distributions 
260*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
261*43a90889SApple OSS Distributions 	rw_fd1 = open(testfile, O_RDWR, 0666);
262*43a90889SApple OSS Distributions 	T_ASSERT_NE(rw_fd1, -1, "Open test fi1e in O_RDWR: %s", testfile);
263*43a90889SApple OSS Distributions 
264*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
265*43a90889SApple OSS Distributions 	rw_fd2 = open(testfile, O_RDWR, 0666);
266*43a90889SApple OSS Distributions 	T_ASSERT_NE(rw_fd2, -1, "Open test fi1e in O_RDWR: %s", testfile);
267*43a90889SApple OSS Distributions 
268*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
269*43a90889SApple OSS Distributions 	fd = open(testfile, O_EVTONLY, 0666);
270*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_EVTONLY: %s", testfile);
271*43a90889SApple OSS Distributions 
272*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
273*43a90889SApple OSS Distributions 	/* Pass in the expected open counts when placing a write lease. */
274*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_SETLEASE_ARG(F_WRLCK, 3));
275*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire write lease: %s", testfile);
276*43a90889SApple OSS Distributions 
277*43a90889SApple OSS Distributions 	kq = kqueue();
278*43a90889SApple OSS Distributions 	T_ASSERT_NE(kq, -1, "Create kqueue");
279*43a90889SApple OSS Distributions 
280*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
281*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
282*43a90889SApple OSS Distributions 	    (NOTE_LEASE_DOWNGRADE | NOTE_LEASE_RELEASE), 0, (void *)testfile);
283*43a90889SApple OSS Distributions 	err = kevent(kq, &lease_kevent, 1, NULL, 0, &kevent_timeout);
284*43a90889SApple OSS Distributions 	T_ASSERT_GE(err, 0, "Register lease event on kq: %d", kq);
285*43a90889SApple OSS Distributions 
286*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = 60;
287*43a90889SApple OSS Distributions 	kevent_timeout.tv_nsec = 0;
288*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
289*43a90889SApple OSS Distributions 
290*43a90889SApple OSS Distributions 	err = kevent(kq, NULL, 0, &lease_kevent, 1, &kevent_timeout);
291*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Listen for lease event on kq: %d", kq);
292*43a90889SApple OSS Distributions 
293*43a90889SApple OSS Distributions 	if (err > 0) {
294*43a90889SApple OSS Distributions 		T_ASSERT_EQ(lease_kevent.fflags, NOTE_LEASE_DOWNGRADE,
295*43a90889SApple OSS Distributions 		    "Got lease event 0x%x", lease_kevent.fflags);
296*43a90889SApple OSS Distributions 
297*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
298*43a90889SApple OSS Distributions 		/* Pass in the expected write counts when placing a read lease. */
299*43a90889SApple OSS Distributions 		err = fcntl(fd, F_SETLEASE, F_SETLEASE_ARG(F_RDLCK, 2));
300*43a90889SApple OSS Distributions 		T_ASSERT_NE(err, -1, "Downgrade to read lease: %s", testfile);
301*43a90889SApple OSS Distributions 	} else {
302*43a90889SApple OSS Distributions 		T_FAIL("Timedout listening for lease event on kq: %d", kq);
303*43a90889SApple OSS Distributions 	}
304*43a90889SApple OSS Distributions }
305*43a90889SApple OSS Distributions 
306*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_read_lease_timedout, "Open file in O_RDONLY mode, acquire read lease, and hold lease beyond lease break timeout upon NOTE_LEASE_RELEASE event", T_META_ASROOT(true))
307*43a90889SApple OSS Distributions {
308*43a90889SApple OSS Distributions 	struct kevent lease_kevent;
309*43a90889SApple OSS Distributions 	struct timespec kevent_timeout;
310*43a90889SApple OSS Distributions 	uint32_t val, new_val;
311*43a90889SApple OSS Distributions 	size_t val_len, new_val_len;
312*43a90889SApple OSS Distributions 	char *testfile = argv[0];
313*43a90889SApple OSS Distributions 	int err, fd, kq;
314*43a90889SApple OSS Distributions 
315*43a90889SApple OSS Distributions 	if (!is_development_kernel()) {
316*43a90889SApple OSS Distributions 		T_SKIP("Skipping test on release kernel");
317*43a90889SApple OSS Distributions 	}
318*43a90889SApple OSS Distributions 
319*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
320*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
321*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
322*43a90889SApple OSS Distributions 
323*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
324*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
325*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read lease: %s", testfile);
326*43a90889SApple OSS Distributions 
327*43a90889SApple OSS Distributions 	new_val = 10;
328*43a90889SApple OSS Distributions 	new_val_len = val_len = sizeof(uint32_t);
329*43a90889SApple OSS Distributions 	err = sysctlbyname("vfs.lease.break_timeout", (void *)&val, &val_len,
330*43a90889SApple OSS Distributions 	    (void *)&new_val, new_val_len);
331*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Change vfs.lease.break_timeout to %d secs", new_val);
332*43a90889SApple OSS Distributions 
333*43a90889SApple OSS Distributions 	kq = kqueue();
334*43a90889SApple OSS Distributions 	T_ASSERT_NE(kq, -1, "Create kqueue");
335*43a90889SApple OSS Distributions 
336*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
337*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
338*43a90889SApple OSS Distributions 	    (NOTE_LEASE_DOWNGRADE | NOTE_LEASE_RELEASE), 0, (void *)testfile);
339*43a90889SApple OSS Distributions 	err = kevent(kq, &lease_kevent, 1, NULL, 0, &kevent_timeout);
340*43a90889SApple OSS Distributions 	T_ASSERT_GE(err, 0, "Register lease event on kq: %d", kq);
341*43a90889SApple OSS Distributions 
342*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = 30;
343*43a90889SApple OSS Distributions 	kevent_timeout.tv_nsec = 0;
344*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
345*43a90889SApple OSS Distributions 
346*43a90889SApple OSS Distributions 	err = kevent(kq, NULL, 0, &lease_kevent, 1, &kevent_timeout);
347*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Listen for lease event on kq: %d", kq);
348*43a90889SApple OSS Distributions 
349*43a90889SApple OSS Distributions 	if (err > 0) {
350*43a90889SApple OSS Distributions 		T_ASSERT_EQ(lease_kevent.fflags, NOTE_LEASE_RELEASE,
351*43a90889SApple OSS Distributions 		    "Got lease event 0x%x", lease_kevent.fflags);
352*43a90889SApple OSS Distributions 
353*43a90889SApple OSS Distributions 		/* Sleep to force lease break timedout. */
354*43a90889SApple OSS Distributions 		T_LOG("Sleep for %d secs to force lease break timedout", new_val + 5);
355*43a90889SApple OSS Distributions 		sleep(new_val + 5);
356*43a90889SApple OSS Distributions 	} else {
357*43a90889SApple OSS Distributions 		T_FAIL("Timedout listening for lease event on kq: %d", kq);
358*43a90889SApple OSS Distributions 	}
359*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Change vfs.lease.break_timeout to %d secs", new_val);
360*43a90889SApple OSS Distributions }
361*43a90889SApple OSS Distributions 
362*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_dir_read_lease, "Open directory in O_RDONLY mode, acquire read lease, and release lease upon NOTE_LEASE_RELEASE event")
363*43a90889SApple OSS Distributions {
364*43a90889SApple OSS Distributions 	struct kevent lease_kevent;
365*43a90889SApple OSS Distributions 	struct timespec kevent_timeout;
366*43a90889SApple OSS Distributions 	char *testdir = argv[1];
367*43a90889SApple OSS Distributions 	int err, dir_fd, kq;
368*43a90889SApple OSS Distributions 
369*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
370*43a90889SApple OSS Distributions 	dir_fd = open(testdir, O_RDONLY);
371*43a90889SApple OSS Distributions 	T_ASSERT_NE(dir_fd, -1, "Open test dir in O_RDONLY: %s", testdir);
372*43a90889SApple OSS Distributions 
373*43a90889SApple OSS Distributions 	kq = kqueue();
374*43a90889SApple OSS Distributions 	T_ASSERT_NE(kq, -1, "Create kqueue");
375*43a90889SApple OSS Distributions 
376*43a90889SApple OSS Distributions retry:
377*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
378*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_SETLEASE, F_RDLCK);
379*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read lease: %s", testdir);
380*43a90889SApple OSS Distributions 
381*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = kevent_timeout.tv_nsec = 0;
382*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, dir_fd, EVFILT_VNODE, (EV_ADD | EV_ENABLE | EV_CLEAR),
383*43a90889SApple OSS Distributions 	    (NOTE_LEASE_DOWNGRADE | NOTE_LEASE_RELEASE), 0, (void *)testdir);
384*43a90889SApple OSS Distributions 	err = kevent(kq, &lease_kevent, 1, NULL, 0, &kevent_timeout);
385*43a90889SApple OSS Distributions 	T_ASSERT_GE(err, 0, "Register lease event on kq: %d", kq);
386*43a90889SApple OSS Distributions 
387*43a90889SApple OSS Distributions 	kevent_timeout.tv_sec = 30;
388*43a90889SApple OSS Distributions 	kevent_timeout.tv_nsec = 0;
389*43a90889SApple OSS Distributions 	EV_SET(&lease_kevent, dir_fd, EVFILT_VNODE, EV_CLEAR, 0, 0, 0);
390*43a90889SApple OSS Distributions 
391*43a90889SApple OSS Distributions 	err = kevent(kq, NULL, 0, &lease_kevent, 1, &kevent_timeout);
392*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Listen for lease event on kq: %d", kq);
393*43a90889SApple OSS Distributions 
394*43a90889SApple OSS Distributions 	if (err > 0) {
395*43a90889SApple OSS Distributions 		T_ASSERT_EQ(lease_kevent.fflags, NOTE_LEASE_RELEASE,
396*43a90889SApple OSS Distributions 		    "Got lease event 0x%x", lease_kevent.fflags);
397*43a90889SApple OSS Distributions 
398*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
399*43a90889SApple OSS Distributions 		err = fcntl(dir_fd, F_SETLEASE, F_UNLCK);
400*43a90889SApple OSS Distributions 		T_ASSERT_NE(err, -1, "Release lease: %s", testdir);
401*43a90889SApple OSS Distributions 
402*43a90889SApple OSS Distributions 		/*
403*43a90889SApple OSS Distributions 		 * Retry until we got no more events (kevent timedout) which means
404*43a90889SApple OSS Distributions 		 * the other helper is done with all the tests.
405*43a90889SApple OSS Distributions 		 */
406*43a90889SApple OSS Distributions 		goto retry;
407*43a90889SApple OSS Distributions 	} else {
408*43a90889SApple OSS Distributions 		T_FAIL("Timedout listening for lease event on kq: %d", kq);
409*43a90889SApple OSS Distributions 	}
410*43a90889SApple OSS Distributions }
411*43a90889SApple OSS Distributions 
412*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdwr, "Open file in O_RDWR mode")
413*43a90889SApple OSS Distributions {
414*43a90889SApple OSS Distributions 	char *testfile = argv[0];
415*43a90889SApple OSS Distributions 	int fd;
416*43a90889SApple OSS Distributions 
417*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
418*43a90889SApple OSS Distributions 	sleep(1);
419*43a90889SApple OSS Distributions 
420*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
421*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDWR, 0666);
422*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDWR: %s", testfile);
423*43a90889SApple OSS Distributions }
424*43a90889SApple OSS Distributions 
425*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly, "Open file in O_RDONLY mode")
426*43a90889SApple OSS Distributions {
427*43a90889SApple OSS Distributions 	char *testfile = argv[0];
428*43a90889SApple OSS Distributions 	int fd;
429*43a90889SApple OSS Distributions 
430*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
431*43a90889SApple OSS Distributions 	sleep(1);
432*43a90889SApple OSS Distributions 
433*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
434*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
435*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
436*43a90889SApple OSS Distributions }
437*43a90889SApple OSS Distributions 
438*43a90889SApple OSS Distributions T_HELPER_DECL(truncate, "Truncate file")
439*43a90889SApple OSS Distributions {
440*43a90889SApple OSS Distributions 	char *testfile = argv[0];
441*43a90889SApple OSS Distributions 	int err;
442*43a90889SApple OSS Distributions 
443*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
444*43a90889SApple OSS Distributions 	sleep(1);
445*43a90889SApple OSS Distributions 
446*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
447*43a90889SApple OSS Distributions 	err = truncate(testfile, 0);
448*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Truncate test fi1e: %s", testfile);
449*43a90889SApple OSS Distributions }
450*43a90889SApple OSS Distributions 
451*43a90889SApple OSS Distributions T_HELPER_DECL(open_rdonly_request_read_range_lock, "Open file in O_RDONLY mode and request byte range lock")
452*43a90889SApple OSS Distributions {
453*43a90889SApple OSS Distributions 	struct flock lreq;
454*43a90889SApple OSS Distributions 	char *testfile = argv[0];
455*43a90889SApple OSS Distributions 	int err, fd;
456*43a90889SApple OSS Distributions 
457*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
458*43a90889SApple OSS Distributions 	sleep(1);
459*43a90889SApple OSS Distributions 
460*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
461*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
462*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
463*43a90889SApple OSS Distributions 
464*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
465*43a90889SApple OSS Distributions 	lreq.l_start = 0;
466*43a90889SApple OSS Distributions 	lreq.l_len = 0;
467*43a90889SApple OSS Distributions 	lreq.l_type = F_RDLCK;
468*43a90889SApple OSS Distributions 	lreq.l_whence = 0;
469*43a90889SApple OSS Distributions 
470*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLK, &lreq);
471*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read range lock on test fi1e: %s", testfile);
472*43a90889SApple OSS Distributions 
473*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
474*43a90889SApple OSS Distributions 	lreq.l_start = 0;
475*43a90889SApple OSS Distributions 	lreq.l_len = 0;
476*43a90889SApple OSS Distributions 	lreq.l_type = F_UNLCK;
477*43a90889SApple OSS Distributions 	lreq.l_whence = 0;
478*43a90889SApple OSS Distributions 
479*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLK, &lreq);
480*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Release read range lock on test fi1e: %s", testfile);
481*43a90889SApple OSS Distributions }
482*43a90889SApple OSS Distributions 
483*43a90889SApple OSS Distributions T_HELPER_DECL(file_syscalls, "Call file syscalls")
484*43a90889SApple OSS Distributions {
485*43a90889SApple OSS Distributions 	char destfile[MAXPATHLEN];
486*43a90889SApple OSS Distributions 	struct attrlist attrlist;
487*43a90889SApple OSS Distributions 	char *xattr_key = "com.apple.xattr_test";
488*43a90889SApple OSS Distributions 	char xattr_val[] = "xattr_foo";
489*43a90889SApple OSS Distributions 	char *testfile = argv[0];
490*43a90889SApple OSS Distributions 	uint32_t flags;
491*43a90889SApple OSS Distributions 	int err, fd;
492*43a90889SApple OSS Distributions 
493*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
494*43a90889SApple OSS Distributions 	sleep(1);
495*43a90889SApple OSS Distributions 
496*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
497*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDWR | O_CREAT, 0666);
498*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDWR|O_CREAT: %s", testfile);
499*43a90889SApple OSS Distributions 	sleep(1);
500*43a90889SApple OSS Distributions 
501*43a90889SApple OSS Distributions 	/* Test ftruncate (fd needs to be opened with write mode) */
502*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
503*43a90889SApple OSS Distributions 	err = ftruncate(fd, 0);
504*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fdtruncate: %s", testfile);
505*43a90889SApple OSS Distributions 	sleep(1);
506*43a90889SApple OSS Distributions 
507*43a90889SApple OSS Distributions 	/* Test (p)write. */
508*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
509*43a90889SApple OSS Distributions 	err = (int)write(fd, destfile, sizeof(destfile));
510*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "write: %s", testfile);
511*43a90889SApple OSS Distributions 	sleep(1);
512*43a90889SApple OSS Distributions 
513*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
514*43a90889SApple OSS Distributions 	err = (int)pwrite(fd, destfile, sizeof(destfile), sizeof(destfile));
515*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "write: %s", testfile);
516*43a90889SApple OSS Distributions 	sleep(1);
517*43a90889SApple OSS Distributions 
518*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", testfile);
519*43a90889SApple OSS Distributions 
520*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
521*43a90889SApple OSS Distributions 	fd = open(testfile, O_RDONLY, 0666);
522*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", testfile);
523*43a90889SApple OSS Distributions 
524*43a90889SApple OSS Distributions 	/* Test (f)chflags syscall */
525*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
526*43a90889SApple OSS Distributions 	err = chflags(testfile, 0);
527*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "chflags: %s", testfile);
528*43a90889SApple OSS Distributions 	sleep(1);
529*43a90889SApple OSS Distributions 
530*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
531*43a90889SApple OSS Distributions 	err = fchflags(fd, 0);
532*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fchflags: %s", testfile);
533*43a90889SApple OSS Distributions 	sleep(1);
534*43a90889SApple OSS Distributions 
535*43a90889SApple OSS Distributions 	/* Test (f)chmod syscall */
536*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
537*43a90889SApple OSS Distributions 	err = chmod(testfile, S_IRWXU);
538*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "chmod: %s", testfile);
539*43a90889SApple OSS Distributions 	sleep(1);
540*43a90889SApple OSS Distributions 
541*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
542*43a90889SApple OSS Distributions 	err = fchmod(fd, S_IRWXU);
543*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fchmod: %s", testfile);
544*43a90889SApple OSS Distributions 	sleep(1);
545*43a90889SApple OSS Distributions 
546*43a90889SApple OSS Distributions 	/* Test clonefile */
547*43a90889SApple OSS Distributions 	snprintf(destfile, sizeof(destfile), "%s.%d", testfile, rand());
548*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
549*43a90889SApple OSS Distributions 	err = clonefile(testfile, destfile, CLONE_NOFOLLOW);
550*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "clonefile src: %s dest: %s", testfile, destfile);
551*43a90889SApple OSS Distributions 	sleep(1);
552*43a90889SApple OSS Distributions 
553*43a90889SApple OSS Distributions 	/* Test copyfile */
554*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
555*43a90889SApple OSS Distributions 	err = copyfile(testfile, destfile, NULL, COPYFILE_DATA | COPYFILE_STAT);
556*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "copyfile src: %s dest: %s", testfile, destfile);
557*43a90889SApple OSS Distributions 	sleep(1);
558*43a90889SApple OSS Distributions 
559*43a90889SApple OSS Distributions 	/* Test unlink */
560*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
561*43a90889SApple OSS Distributions 	err = unlink(destfile);
562*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "unlink: %s", destfile);
563*43a90889SApple OSS Distributions 	sleep(1);
564*43a90889SApple OSS Distributions 
565*43a90889SApple OSS Distributions 	/* Test (f)setxattr and (f)removexattr */
566*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
567*43a90889SApple OSS Distributions 	err = setxattr(testfile, xattr_key, &xattr_val[0], sizeof(xattr_val), 0, 0);
568*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "setxattr: %s", testfile);
569*43a90889SApple OSS Distributions 	sleep(1);
570*43a90889SApple OSS Distributions 
571*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
572*43a90889SApple OSS Distributions 	err = removexattr(testfile, xattr_key, 0);
573*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "removexattr: %s", testfile);
574*43a90889SApple OSS Distributions 	sleep(1);
575*43a90889SApple OSS Distributions 
576*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
577*43a90889SApple OSS Distributions 	err = fsetxattr(fd, xattr_key, &xattr_val[0], sizeof(xattr_val), 0, 0);
578*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fsetxattr: %s", testfile);
579*43a90889SApple OSS Distributions 	sleep(1);
580*43a90889SApple OSS Distributions 
581*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
582*43a90889SApple OSS Distributions 	err = fremovexattr(fd, xattr_key, 0);
583*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fremovexattr: %s", testfile);
584*43a90889SApple OSS Distributions 	sleep(1);
585*43a90889SApple OSS Distributions 
586*43a90889SApple OSS Distributions 	/* Test (f)setattrlist */
587*43a90889SApple OSS Distributions 	flags = 0;
588*43a90889SApple OSS Distributions 	memset(&attrlist, 0, sizeof(attrlist));
589*43a90889SApple OSS Distributions 	attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
590*43a90889SApple OSS Distributions 	attrlist.commonattr = (ATTR_CMN_FLAGS);
591*43a90889SApple OSS Distributions 
592*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
593*43a90889SApple OSS Distributions 	err = setattrlist(testfile, &attrlist, &flags, sizeof(flags), 0);
594*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "setattrlist: %s", testfile);
595*43a90889SApple OSS Distributions 	sleep(1);
596*43a90889SApple OSS Distributions 
597*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
598*43a90889SApple OSS Distributions 	err = fsetattrlist(fd, &attrlist, &flags, sizeof(flags), 0);
599*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "fsetattrlist: %s", testfile);
600*43a90889SApple OSS Distributions 	sleep(1);
601*43a90889SApple OSS Distributions 
602*43a90889SApple OSS Distributions 	/* Test truncate */
603*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
604*43a90889SApple OSS Distributions 	err = truncate(testfile, 0);
605*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "truncate: %s", testfile);
606*43a90889SApple OSS Distributions 	sleep(1);
607*43a90889SApple OSS Distributions 
608*43a90889SApple OSS Distributions 	/* Test (f)utimes */
609*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
610*43a90889SApple OSS Distributions 	err = utimes(testfile, NULL);
611*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "utimes: %s", testfile);
612*43a90889SApple OSS Distributions 	sleep(1);
613*43a90889SApple OSS Distributions 
614*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
615*43a90889SApple OSS Distributions 	err = futimes(fd, NULL);
616*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "futimes: %s", testfile);
617*43a90889SApple OSS Distributions 
618*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", testfile);
619*43a90889SApple OSS Distributions }
620*43a90889SApple OSS Distributions 
621*43a90889SApple OSS Distributions T_HELPER_DECL(file_syscalls_2, "Call file syscalls (mknod)", T_META_ASROOT(true))
622*43a90889SApple OSS Distributions {
623*43a90889SApple OSS Distributions 	char destfile[MAXPATHLEN];
624*43a90889SApple OSS Distributions 	char *testfile = argv[0];
625*43a90889SApple OSS Distributions 	int err;
626*43a90889SApple OSS Distributions 
627*43a90889SApple OSS Distributions 	snprintf(destfile, sizeof(destfile), "%s.%d", testfile, rand());
628*43a90889SApple OSS Distributions 
629*43a90889SApple OSS Distributions 	/* wait for the other helper to be in ready state */
630*43a90889SApple OSS Distributions 	sleep(1);
631*43a90889SApple OSS Distributions 
632*43a90889SApple OSS Distributions 	/* Test mknod */
633*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
634*43a90889SApple OSS Distributions 	err = mknod(destfile, (S_IFCHR | S_IRWXU), 0);
635*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "mknod: %s", destfile);
636*43a90889SApple OSS Distributions 	sleep(1);
637*43a90889SApple OSS Distributions 
638*43a90889SApple OSS Distributions 	/* Test unlink */
639*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
640*43a90889SApple OSS Distributions 	err = unlink(destfile);
641*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "unlink: %s", destfile);
642*43a90889SApple OSS Distributions }
643*43a90889SApple OSS Distributions 
644*43a90889SApple OSS Distributions /*
645*43a90889SApple OSS Distributions  * Test acquire, downgrade, and release lease.
646*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode
647*43a90889SApple OSS Distributions  * b. Process A acquires write lease
648*43a90889SApple OSS Distributions  * c. Process A downgrade from write to read lease
649*43a90889SApple OSS Distributions  * d. Process A release lease
650*43a90889SApple OSS Distributions  *
651*43a90889SApple OSS Distributions  * Result: Lease operations should succeed as expected.
652*43a90889SApple OSS Distributions  */
653*43a90889SApple OSS Distributions T_DECL(acquire_downgrade_release, "Test acquire, downgrade and release lease", T_META_ENABLED(TARGET_OS_OSX))
654*43a90889SApple OSS Distributions {
655*43a90889SApple OSS Distributions 	int err, fd;
656*43a90889SApple OSS Distributions 
657*43a90889SApple OSS Distributions 	create_test_file();
658*43a90889SApple OSS Distributions 
659*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
660*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDONLY, 0666);
661*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", g_testfile);
662*43a90889SApple OSS Distributions 
663*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
664*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
665*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire write lease: %s", g_testfile);
666*43a90889SApple OSS Distributions 
667*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
668*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
669*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_WRLCK, "Retrieve lease: %s", g_testfile);
670*43a90889SApple OSS Distributions 
671*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
672*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
673*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Downgrade to read lease: %s", g_testfile);
674*43a90889SApple OSS Distributions 
675*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
676*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
677*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_RDLCK, "Retrieve lease: %s", g_testfile);
678*43a90889SApple OSS Distributions 
679*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
680*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_UNLCK);
681*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Release lease: %s", g_testfile);
682*43a90889SApple OSS Distributions 
683*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
684*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
685*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testfile);
686*43a90889SApple OSS Distributions 
687*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
688*43a90889SApple OSS Distributions }
689*43a90889SApple OSS Distributions 
690*43a90889SApple OSS Distributions /*
691*43a90889SApple OSS Distributions  * Test acquire lease failure due to open conflicts.
692*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDWR mode
693*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDONLY mode
694*43a90889SApple OSS Distributions  * c. Process B tries to acquire read lease
695*43a90889SApple OSS Distributions  *
696*43a90889SApple OSS Distributions  * Result: Process B should fail to acquire read lease with EAGAIN due to the
697*43a90889SApple OSS Distributions  *         file has been opened with write mode (O_RDWR).
698*43a90889SApple OSS Distributions  */
699*43a90889SApple OSS Distributions T_DECL(open_conflict_1, "Test acquire read lease failure due to open conflicts", T_META_ENABLED(TARGET_OS_OSX))
700*43a90889SApple OSS Distributions {
701*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_acquire_read_lease_EAGAIN"};
702*43a90889SApple OSS Distributions 	int fd;
703*43a90889SApple OSS Distributions 
704*43a90889SApple OSS Distributions 	create_test_file();
705*43a90889SApple OSS Distributions 
706*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
707*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDWR, 0666);
708*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDWR: %s", g_testfile);
709*43a90889SApple OSS Distributions 
710*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 1);
711*43a90889SApple OSS Distributions 
712*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
713*43a90889SApple OSS Distributions }
714*43a90889SApple OSS Distributions 
715*43a90889SApple OSS Distributions /*
716*43a90889SApple OSS Distributions  * Test acquire lease failure due to open conflicts.
717*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode
718*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDWR mode
719*43a90889SApple OSS Distributions  * c. Process B tries to acquire write lease
720*43a90889SApple OSS Distributions  *
721*43a90889SApple OSS Distributions  * Result: Process B should fail to acquire write lease with EAGAIN due to the
722*43a90889SApple OSS Distributions  *         file has been opened elsewhere.
723*43a90889SApple OSS Distributions  */
724*43a90889SApple OSS Distributions T_DECL(open_conflict_2, "Test acquire write lease failure due to open conflicts", T_META_ENABLED(TARGET_OS_OSX))
725*43a90889SApple OSS Distributions {
726*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdwr_acquire_write_lease_EAGAIN"};
727*43a90889SApple OSS Distributions 	int fd;
728*43a90889SApple OSS Distributions 
729*43a90889SApple OSS Distributions 	create_test_file();
730*43a90889SApple OSS Distributions 
731*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
732*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDONLY, 0666);
733*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", g_testfile);
734*43a90889SApple OSS Distributions 
735*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 1);
736*43a90889SApple OSS Distributions 
737*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close test file: %s", g_testfile);
738*43a90889SApple OSS Distributions }
739*43a90889SApple OSS Distributions 
740*43a90889SApple OSS Distributions /*
741*43a90889SApple OSS Distributions  * Test multiple processes put a read lease on the file.
742*43a90889SApple OSS Distributions  * a. Process A opens the file with O_RDONLY mode and place a read lease
743*43a90889SApple OSS Distributions  * b. Process B opens the file with O_RDONLY mode and place a read lease
744*43a90889SApple OSS Distributions  *
745*43a90889SApple OSS Distributions  * Result: Both processes should succeed in placing read lease on the file.
746*43a90889SApple OSS Distributions  */
747*43a90889SApple OSS Distributions T_DECL(multiple_read_leases, "Test multiple processes put a read lease on the file", T_META_ENABLED(TARGET_OS_OSX))
748*43a90889SApple OSS Distributions {
749*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_acquire_read_lease_succeed",
750*43a90889SApple OSS Distributions 		                           "open_rdonly_acquire_read_lease_succeed"};
751*43a90889SApple OSS Distributions 
752*43a90889SApple OSS Distributions 	create_test_file();
753*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
754*43a90889SApple OSS Distributions }
755*43a90889SApple OSS Distributions 
756*43a90889SApple OSS Distributions /*
757*43a90889SApple OSS Distributions  * Test acquire and release lease when there is no lease is in place.
758*43a90889SApple OSS Distributions  *
759*43a90889SApple OSS Distributions  * Result: Acquire lease should succeed with F_UNLCK (no lease).
760*43a90889SApple OSS Distributions  *         Release lease should fail with ENOLCK.
761*43a90889SApple OSS Distributions  */
762*43a90889SApple OSS Distributions T_DECL(acquire_release_no_lease, "Test acquire and release lease when there is no lease is in place", T_META_ENABLED(TARGET_OS_OSX))
763*43a90889SApple OSS Distributions {
764*43a90889SApple OSS Distributions 	int err, fd;
765*43a90889SApple OSS Distributions 
766*43a90889SApple OSS Distributions 	create_test_file();
767*43a90889SApple OSS Distributions 
768*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
769*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDWR, 0666);
770*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDWR: %s", g_testfile);
771*43a90889SApple OSS Distributions 
772*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
773*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
774*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testfile);
775*43a90889SApple OSS Distributions 
776*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
777*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_UNLCK);
778*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == ENOLCK), "Release lease: %s",
779*43a90889SApple OSS Distributions 	    g_testfile);
780*43a90889SApple OSS Distributions }
781*43a90889SApple OSS Distributions 
782*43a90889SApple OSS Distributions /*
783*43a90889SApple OSS Distributions  * Test acquire, release and retrieve lease on non-regular file.
784*43a90889SApple OSS Distributions  *
785*43a90889SApple OSS Distributions  * Result: Acquire, release and retrieve lease should fail with EBADF.
786*43a90889SApple OSS Distributions  */
787*43a90889SApple OSS Distributions T_DECL(acquire_release_retrieve_non_file, "Test acquire, release and retrieve lease on non-regular file", T_META_ENABLED(TARGET_OS_OSX))
788*43a90889SApple OSS Distributions {
789*43a90889SApple OSS Distributions 	int err, fd;
790*43a90889SApple OSS Distributions 
791*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
792*43a90889SApple OSS Distributions 	fd = socket(AF_UNIX, SOCK_STREAM, 0);
793*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open socket");
794*43a90889SApple OSS Distributions 
795*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
796*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_RDLCK);
797*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EBADF), "Acquire read lease on socket");
798*43a90889SApple OSS Distributions 
799*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
800*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
801*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EBADF), "Acquire write lease on socket");
802*43a90889SApple OSS Distributions 
803*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
804*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_UNLCK);
805*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EBADF), "Release lease on socket");
806*43a90889SApple OSS Distributions 
807*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
808*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
809*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == EBADF), "Retrieve lease on socket");
810*43a90889SApple OSS Distributions 
811*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close socket");
812*43a90889SApple OSS Distributions }
813*43a90889SApple OSS Distributions 
814*43a90889SApple OSS Distributions /*
815*43a90889SApple OSS Distributions  * Test retrieve and downgrade lease with duplicated fd created with dup(2).
816*43a90889SApple OSS Distributions  * a. Process A opens the file with O_RDONLY mode and place a write lease
817*43a90889SApple OSS Distributions  * b. Process A duplicates the existing file descriptor
818*43a90889SApple OSS Distributions  * c. Process A retrieves and downgrade lease with duplicated fd
819*43a90889SApple OSS Distributions  * d. Process A closes the original and duplicated fds to release lease.
820*43a90889SApple OSS Distributions  *
821*43a90889SApple OSS Distributions  * Result: Retrieve and downgrade with duplicated fd should succeed.
822*43a90889SApple OSS Distributions  *         When all fds are closed, lease should be released implicity.
823*43a90889SApple OSS Distributions  */
824*43a90889SApple OSS Distributions T_DECL(retrieve_downgrade_dup_fd, "Test retrieve and downgrade lease with duplicated fd created with dup()", T_META_ENABLED(TARGET_OS_OSX))
825*43a90889SApple OSS Distributions {
826*43a90889SApple OSS Distributions 	int err, dup_fd, fd;
827*43a90889SApple OSS Distributions 
828*43a90889SApple OSS Distributions 	create_test_file();
829*43a90889SApple OSS Distributions 
830*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
831*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDONLY, 0666);
832*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", g_testfile);
833*43a90889SApple OSS Distributions 
834*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
835*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
836*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testfile);
837*43a90889SApple OSS Distributions 
838*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
839*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
840*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire write lease: %s", g_testfile);
841*43a90889SApple OSS Distributions 
842*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
843*43a90889SApple OSS Distributions 	dup_fd = dup(fd);
844*43a90889SApple OSS Distributions 	T_ASSERT_NE(dup_fd, -1, "Duplicate existing fd: %d", fd);
845*43a90889SApple OSS Distributions 
846*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
847*43a90889SApple OSS Distributions 	err = fcntl(dup_fd, F_GETLEASE);
848*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_WRLCK, "Retrieve lease with dup fd: %d", dup_fd);
849*43a90889SApple OSS Distributions 
850*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
851*43a90889SApple OSS Distributions 	err = fcntl(dup_fd, F_SETLEASE, F_RDLCK);
852*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Downgrade to read lease with dup fd: %d", dup_fd);
853*43a90889SApple OSS Distributions 
854*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
855*43a90889SApple OSS Distributions 	err = fcntl(dup_fd, F_GETLEASE);
856*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_RDLCK, "Retrieve lease with dup fd: %d", dup_fd);
857*43a90889SApple OSS Distributions 
858*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close original fd");
859*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(dup_fd), "Close duplicated fd");
860*43a90889SApple OSS Distributions 
861*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
862*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDONLY, 0666);
863*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", g_testfile);
864*43a90889SApple OSS Distributions 
865*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
866*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
867*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testfile);
868*43a90889SApple OSS Distributions 
869*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(fd), "Close fd");
870*43a90889SApple OSS Distributions }
871*43a90889SApple OSS Distributions 
872*43a90889SApple OSS Distributions /*
873*43a90889SApple OSS Distributions  * Test retrieve and release lease with duplicated fd created with fork(2).
874*43a90889SApple OSS Distributions  * a. Process A opens the file with O_RDONLY mode and place a write lease
875*43a90889SApple OSS Distributions  * b. Process A forks to create a child process
876*43a90889SApple OSS Distributions  * c. Child process retrieves and releases lease with duplicated fd
877*43a90889SApple OSS Distributions  * d. Child process exits
878*43a90889SApple OSS Distributions  * e. Process A verifies the lease has been released
879*43a90889SApple OSS Distributions  *
880*43a90889SApple OSS Distributions  * Result: Retrieve and release with duplicated fd should succeed.
881*43a90889SApple OSS Distributions  *         Child process should be able to release the leased placed by the
882*43a90889SApple OSS Distributions  *         parent process.
883*43a90889SApple OSS Distributions  */
884*43a90889SApple OSS Distributions T_DECL(retrieve_release_fork_fd, "Test retrieve and release lease with duplicated fd created with fork()", T_META_ENABLED(TARGET_OS_OSX))
885*43a90889SApple OSS Distributions {
886*43a90889SApple OSS Distributions 	pid_t child_pid;
887*43a90889SApple OSS Distributions 	int err, fd;
888*43a90889SApple OSS Distributions 
889*43a90889SApple OSS Distributions 	create_test_file();
890*43a90889SApple OSS Distributions 
891*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
892*43a90889SApple OSS Distributions 	fd = open(g_testfile, O_RDONLY, 0666);
893*43a90889SApple OSS Distributions 	T_ASSERT_NE(fd, -1, "Open test fi1e in O_RDONLY: %s", g_testfile);
894*43a90889SApple OSS Distributions 
895*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
896*43a90889SApple OSS Distributions 	err = fcntl(fd, F_GETLEASE);
897*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testfile);
898*43a90889SApple OSS Distributions 
899*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
900*43a90889SApple OSS Distributions 	err = fcntl(fd, F_SETLEASE, F_WRLCK);
901*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire write lease: %s", g_testfile);
902*43a90889SApple OSS Distributions 
903*43a90889SApple OSS Distributions 	child_pid = fork();
904*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(child_pid, "Fork process");
905*43a90889SApple OSS Distributions 
906*43a90889SApple OSS Distributions 	if (child_pid == 0) {
907*43a90889SApple OSS Distributions 		/* child process */
908*43a90889SApple OSS Distributions 		err = fcntl(fd, F_GETLEASE);
909*43a90889SApple OSS Distributions 		T_ASSERT_EQ(err, F_WRLCK, "Retrieve lease with fork fd: %d", fd);
910*43a90889SApple OSS Distributions 
911*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
912*43a90889SApple OSS Distributions 		err = fcntl(fd, F_SETLEASE, F_UNLCK);
913*43a90889SApple OSS Distributions 		T_ASSERT_NE(err, -1, "Release lease with fork fd: %d", fd);
914*43a90889SApple OSS Distributions 
915*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
916*43a90889SApple OSS Distributions 		err = fcntl(fd, F_GETLEASE);
917*43a90889SApple OSS Distributions 		T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease with fork fd: %d", fd);
918*43a90889SApple OSS Distributions 
919*43a90889SApple OSS Distributions 		exit(0);
920*43a90889SApple OSS Distributions 	} else {
921*43a90889SApple OSS Distributions 		/* wait for child process to exit */
922*43a90889SApple OSS Distributions 		if (dt_waitpid(child_pid, &err, NULL, 30) == false) {
923*43a90889SApple OSS Distributions 			T_FAIL("dt_waitpid() failed on child pid %d", child_pid);
924*43a90889SApple OSS Distributions 		}
925*43a90889SApple OSS Distributions 
926*43a90889SApple OSS Distributions 		T_WITH_ERRNO;
927*43a90889SApple OSS Distributions 		err = fcntl(fd, F_GETLEASE);
928*43a90889SApple OSS Distributions 		T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease with parent fd: %d", fd);
929*43a90889SApple OSS Distributions 
930*43a90889SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(close(fd), "Close fd");
931*43a90889SApple OSS Distributions 	}
932*43a90889SApple OSS Distributions }
933*43a90889SApple OSS Distributions 
934*43a90889SApple OSS Distributions /*
935*43a90889SApple OSS Distributions  * Test lease break release event.
936*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a read lease
937*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDWR mode and open syscall is blocked
938*43a90889SApple OSS Distributions  * c. Lease break release event is sent to Process A
939*43a90889SApple OSS Distributions  *
940*43a90889SApple OSS Distributions  * Result: Process A releases the lease and process B's open is unblocked
941*43a90889SApple OSS Distributions  */
942*43a90889SApple OSS Distributions T_DECL(lease_break_release_1, "Test lease break release event when file is opened in O_RDWR mode", T_META_ENABLED(TARGET_OS_OSX))
943*43a90889SApple OSS Distributions {
944*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_read_lease_release", "open_rdwr"};
945*43a90889SApple OSS Distributions 
946*43a90889SApple OSS Distributions 	create_test_file();
947*43a90889SApple OSS Distributions 
948*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
949*43a90889SApple OSS Distributions }
950*43a90889SApple OSS Distributions 
951*43a90889SApple OSS Distributions /*
952*43a90889SApple OSS Distributions  * Test lease break release event.
953*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a read lease
954*43a90889SApple OSS Distributions  * b. Process B truncates the file and truncate syscall is blocked
955*43a90889SApple OSS Distributions  * c. Lease break release event is sent to Process A
956*43a90889SApple OSS Distributions  *
957*43a90889SApple OSS Distributions  * Result: Process A releases the lease and process B's truncate is unblocked.
958*43a90889SApple OSS Distributions  */
959*43a90889SApple OSS Distributions T_DECL(lease_break_release_2, "Test lease break release event when file is truncated", T_META_ENABLED(TARGET_OS_OSX))
960*43a90889SApple OSS Distributions {
961*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_read_lease_release", "truncate"};
962*43a90889SApple OSS Distributions 
963*43a90889SApple OSS Distributions 	create_test_file();
964*43a90889SApple OSS Distributions 
965*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
966*43a90889SApple OSS Distributions }
967*43a90889SApple OSS Distributions 
968*43a90889SApple OSS Distributions /*
969*43a90889SApple OSS Distributions  * Test lease break release event.
970*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a read lease
971*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDONLY mode and requests byte range lock
972*43a90889SApple OSS Distributions  *    via fcntl(F_SETLK or F_OFD_SETLK)
973*43a90889SApple OSS Distributions  * c. Lease break release event is sent to Process A
974*43a90889SApple OSS Distributions  *
975*43a90889SApple OSS Distributions  * Result: Process A releases the lease and process B's fcntl call is unblocked.
976*43a90889SApple OSS Distributions  */
977*43a90889SApple OSS Distributions T_DECL(lease_break_release_3, "Test lease break release event when byte range lock is requested", T_META_ENABLED(TARGET_OS_OSX))
978*43a90889SApple OSS Distributions {
979*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_read_lease_release", "open_rdonly_request_read_range_lock"};
980*43a90889SApple OSS Distributions 
981*43a90889SApple OSS Distributions 	create_test_file();
982*43a90889SApple OSS Distributions 
983*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
984*43a90889SApple OSS Distributions }
985*43a90889SApple OSS Distributions 
986*43a90889SApple OSS Distributions /*
987*43a90889SApple OSS Distributions  * Test lease break release event.
988*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a read lease
989*43a90889SApple OSS Distributions  * a. Process B opens the file in O_RDONLY mode and place a read lease
990*43a90889SApple OSS Distributions  * b. Process C opens the file in O_RDWR mode and open syscall is blocked
991*43a90889SApple OSS Distributions  * c. Lease break release events are sent to Process A and B
992*43a90889SApple OSS Distributions  *
993*43a90889SApple OSS Distributions  * Result: Process A and B release the lease and process C's open is unblocked
994*43a90889SApple OSS Distributions  */
995*43a90889SApple OSS Distributions T_DECL(lease_break_release_4, "Test multiple lease break release events", T_META_ENABLED(TARGET_OS_OSX))
996*43a90889SApple OSS Distributions {
997*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_read_lease_release",
998*43a90889SApple OSS Distributions 		                           "open_rdonly_read_lease_release", "open_rdwr"};
999*43a90889SApple OSS Distributions 
1000*43a90889SApple OSS Distributions 	create_test_file();
1001*43a90889SApple OSS Distributions 
1002*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 3);
1003*43a90889SApple OSS Distributions }
1004*43a90889SApple OSS Distributions 
1005*43a90889SApple OSS Distributions /*
1006*43a90889SApple OSS Distributions  * Test lease break downgrade event.
1007*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a write lease
1008*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDONLY mode and open syscall is blocked
1009*43a90889SApple OSS Distributions  * c. Lease break downgrade event is sent to Process A
1010*43a90889SApple OSS Distributions  *
1011*43a90889SApple OSS Distributions  * Result: Process A downgrades the lease and process B's open is unblocked.
1012*43a90889SApple OSS Distributions  */
1013*43a90889SApple OSS Distributions T_DECL(lease_break_downgrade_1, "Test lease break downgrade event with read-only opens", T_META_ENABLED(TARGET_OS_OSX))
1014*43a90889SApple OSS Distributions {
1015*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_write_lease_downgrade", "open_rdonly"};
1016*43a90889SApple OSS Distributions 
1017*43a90889SApple OSS Distributions 	create_test_file();
1018*43a90889SApple OSS Distributions 
1019*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
1020*43a90889SApple OSS Distributions }
1021*43a90889SApple OSS Distributions 
1022*43a90889SApple OSS Distributions /*
1023*43a90889SApple OSS Distributions  * Test lease break downgrade event.
1024*43a90889SApple OSS Distributions  * a. Process A opens the file multiple times in O_RDWR mode and place a
1025*43a90889SApple OSS Distributions  *    write lease
1026*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDONLY mode and open syscall is blocked
1027*43a90889SApple OSS Distributions  * c. Lease break downgrade event is sent to Process A
1028*43a90889SApple OSS Distributions  *
1029*43a90889SApple OSS Distributions  * Result: Process A downgrades the lease and process B's open is unblocked.
1030*43a90889SApple OSS Distributions  */
1031*43a90889SApple OSS Distributions T_DECL(lease_break_downgrade_2, "Test lease break downgrade event with multiple read-write opens", T_META_ENABLED(TARGET_OS_OSX))
1032*43a90889SApple OSS Distributions {
1033*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rw_write_lease_downgrade", "open_rdonly"};
1034*43a90889SApple OSS Distributions 
1035*43a90889SApple OSS Distributions 	create_test_file();
1036*43a90889SApple OSS Distributions 
1037*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
1038*43a90889SApple OSS Distributions }
1039*43a90889SApple OSS Distributions 
1040*43a90889SApple OSS Distributions /*
1041*43a90889SApple OSS Distributions  * Test lease break timedout
1042*43a90889SApple OSS Distributions  * a. Process A opens the file in O_RDONLY mode and place a read lease
1043*43a90889SApple OSS Distributions  * b. Process B opens the file in O_RDWR mode and open syscall is blocked
1044*43a90889SApple OSS Distributions  * c. Lease break release event is sent to Process A
1045*43a90889SApple OSS Distributions  * d. Lease is not release within sysctl's 'vfs.lease.break_timeout'
1046*43a90889SApple OSS Distributions  *
1047*43a90889SApple OSS Distributions  * Result: Kernel forcibly breaks the lease and process B's open is unblocked.
1048*43a90889SApple OSS Distributions  */
1049*43a90889SApple OSS Distributions T_DECL(lease_break_timedout, "Test lease break timedout", T_META_ENABLED(TARGET_OS_OSX))
1050*43a90889SApple OSS Distributions {
1051*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_read_lease_timedout", "open_rdwr"};
1052*43a90889SApple OSS Distributions 
1053*43a90889SApple OSS Distributions 	create_test_file();
1054*43a90889SApple OSS Distributions 
1055*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
1056*43a90889SApple OSS Distributions }
1057*43a90889SApple OSS Distributions 
1058*43a90889SApple OSS Distributions /*
1059*43a90889SApple OSS Distributions  * Test acquire and release lease on directory.
1060*43a90889SApple OSS Distributions  * a. Process A opens the directory in O_RDONLY mode
1061*43a90889SApple OSS Distributions  * b. Process A acquires read lease
1062*43a90889SApple OSS Distributions  * d. Process A release lease
1063*43a90889SApple OSS Distributions  *
1064*43a90889SApple OSS Distributions  * Result: Lease operations should succeed as expected.
1065*43a90889SApple OSS Distributions  */
1066*43a90889SApple OSS Distributions T_DECL(acquire_release_read_lease_dir, "Test acquire and release read lease", T_META_ENABLED(TARGET_OS_OSX))
1067*43a90889SApple OSS Distributions {
1068*43a90889SApple OSS Distributions 	int err, dir_fd;
1069*43a90889SApple OSS Distributions 
1070*43a90889SApple OSS Distributions 	create_test_file();
1071*43a90889SApple OSS Distributions 
1072*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1073*43a90889SApple OSS Distributions 	dir_fd = open(g_testdir, O_RDONLY);
1074*43a90889SApple OSS Distributions 	T_ASSERT_NE(dir_fd, -1, "Open test dir in O_RDONLY: %s", g_testdir);
1075*43a90889SApple OSS Distributions 
1076*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1077*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_SETLEASE, F_RDLCK);
1078*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Acquire read lease: %s", g_testdir);
1079*43a90889SApple OSS Distributions 
1080*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1081*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_GETLEASE);
1082*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_RDLCK, "Retrieve lease: %s", g_testdir);
1083*43a90889SApple OSS Distributions 
1084*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1085*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_SETLEASE, F_UNLCK);
1086*43a90889SApple OSS Distributions 	T_ASSERT_NE(err, -1, "Release lease: %s", g_testdir);
1087*43a90889SApple OSS Distributions 
1088*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1089*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_GETLEASE);
1090*43a90889SApple OSS Distributions 	T_ASSERT_EQ(err, F_UNLCK, "Retrieve lease: %s", g_testdir);
1091*43a90889SApple OSS Distributions 
1092*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(dir_fd), "Close test dir: %s", g_testdir);
1093*43a90889SApple OSS Distributions }
1094*43a90889SApple OSS Distributions 
1095*43a90889SApple OSS Distributions /*
1096*43a90889SApple OSS Distributions  * Test acquire write lease on directory.
1097*43a90889SApple OSS Distributions  *
1098*43a90889SApple OSS Distributions  * Result: Acquire write lease should fail with EBADF.
1099*43a90889SApple OSS Distributions  */
1100*43a90889SApple OSS Distributions T_DECL(acquire_write_lease_dir, "Test acquire write lease on directory", T_META_ENABLED(TARGET_OS_OSX))
1101*43a90889SApple OSS Distributions {
1102*43a90889SApple OSS Distributions 	int err, dir_fd;
1103*43a90889SApple OSS Distributions 
1104*43a90889SApple OSS Distributions 	create_test_file();
1105*43a90889SApple OSS Distributions 
1106*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1107*43a90889SApple OSS Distributions 	dir_fd = open(g_testdir, O_RDONLY);
1108*43a90889SApple OSS Distributions 	T_ASSERT_NE(dir_fd, -1, "Open test dir in O_RDONLY: %s", g_testdir);
1109*43a90889SApple OSS Distributions 
1110*43a90889SApple OSS Distributions 	T_WITH_ERRNO;
1111*43a90889SApple OSS Distributions 	err = fcntl(dir_fd, F_SETLEASE, F_WRLCK);
1112*43a90889SApple OSS Distributions 	T_ASSERT_TRUE((err == -1) && (errno == ENOTSUP), "Acquire write lease on directory: %s", g_testdir);
1113*43a90889SApple OSS Distributions 
1114*43a90889SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(dir_fd), "Close test dir");
1115*43a90889SApple OSS Distributions }
1116*43a90889SApple OSS Distributions 
1117*43a90889SApple OSS Distributions /*
1118*43a90889SApple OSS Distributions  * Test lease break release event for directory read leasing.
1119*43a90889SApple OSS Distributions  * a. Process A opens the directory in O_RDONLY mode and place a read lease
1120*43a90889SApple OSS Distributions  * b. Process B performs various syscalls that can cause its directory contents
1121*43a90889SApple OSS Distributions  *    (namespace) to change, modify contents or change attributes on the
1122*43a90889SApple OSS Distributions  *    immediate files.
1123*43a90889SApple OSS Distributions  *
1124*43a90889SApple OSS Distributions  * Result: Process A releases the lease and process B's syscall is unblocked.
1125*43a90889SApple OSS Distributions  */
1126*43a90889SApple OSS Distributions T_DECL(read_lease_dir_1, "Test directory read leasing and lease break events", T_META_ENABLED(TARGET_OS_OSX))
1127*43a90889SApple OSS Distributions {
1128*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_dir_read_lease", "file_syscalls"};
1129*43a90889SApple OSS Distributions 
1130*43a90889SApple OSS Distributions 	create_test_file();
1131*43a90889SApple OSS Distributions 
1132*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
1133*43a90889SApple OSS Distributions }
1134*43a90889SApple OSS Distributions 
1135*43a90889SApple OSS Distributions T_DECL(read_lease_dir_2, "Test directory read leasing and lease break events", T_META_ENABLED(TARGET_OS_OSX))
1136*43a90889SApple OSS Distributions {
1137*43a90889SApple OSS Distributions 	const char *helper_test_names[] = {"open_rdonly_dir_read_lease", "file_syscalls_2"};
1138*43a90889SApple OSS Distributions 
1139*43a90889SApple OSS Distributions 	create_test_file();
1140*43a90889SApple OSS Distributions 
1141*43a90889SApple OSS Distributions 	run_helpers(helper_test_names, 2);
1142*43a90889SApple OSS Distributions }
1143