flock.c revision 192949
1/*-
2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3 * Authors: Doug Rabson <dfr@rabson.org>
4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/tools/regression/file/flock/flock.c 192949 2009-05-28 02:39:07Z zml $
28 */
29
30#include <sys/time.h>
31#ifdef __FreeBSD__
32#include <sys/mount.h>
33#endif
34#include <sys/stat.h>
35#include <sys/wait.h>
36
37#include <err.h>
38#include <errno.h>
39#include <fcntl.h>
40#include <pthread.h>
41#include <signal.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include <unistd.h>
46
47#ifdef __FreeBSD__
48#if __FreeBSD_version >= 800028
49#define HAVE_SYSID
50#endif
51#include <sys/cdefs.h>
52#else
53#ifndef __unused
54#define __unused
55#endif
56#endif
57
58int verbose = 0;
59
60static int
61make_file(const char *pathname, off_t sz)
62{
63	struct stat st;
64	const char *template = "/flocktempXXXXXX";
65	size_t len;
66	char *filename;
67	int fd;
68
69	if (stat(pathname, &st) == 0) {
70		if (S_ISREG(st.st_mode)) {
71			fd = open(pathname, O_RDWR);
72			if (fd < 0)
73				err(1, "open(%s)", pathname);
74			if (ftruncate(fd, sz) < 0)
75				err(1, "ftruncate");
76			return (fd);
77		}
78	}
79
80	len = strlen(pathname) + strlen(template) + 1;
81	filename = malloc(len);
82	strcpy(filename, pathname);
83	strcat(filename, template);
84	fd = mkstemp(filename);
85	if (fd < 0)
86		err(1, "mkstemp");
87	if (ftruncate(fd, sz) < 0)
88		err(1, "ftruncate");
89	if (unlink(filename) < 0)
90		err(1, "unlink");
91	free(filename);
92
93	return (fd);
94}
95
96static void
97ignore_alarm(int __unused sig)
98{
99}
100
101static int
102safe_waitpid(pid_t pid)
103{
104	int save_errno;
105	int status;
106
107	save_errno = errno;
108	errno = 0;
109	while (waitpid(pid, &status, 0) != pid) {
110		if (errno == EINTR)
111			continue;
112		err(1, "waitpid");
113	}
114	errno = save_errno;
115
116	return (status);
117}
118
119#define FAIL(test)					\
120	do {						\
121		if (test) {				\
122			printf("FAIL (%s)\n", #test);	\
123			return -1;			\
124		}					\
125	} while (0)
126
127#define SUCCEED \
128	do { printf("SUCCEED\n"); return 0; } while (0)
129
130/*
131 * Test 1 - F_GETLK on unlocked region
132 *
133 * If no lock is found that would prevent this lock from being
134 * created, the structure is left unchanged by this function call
135 * except for the lock type which is set to F_UNLCK.
136 */
137static int
138test1(int fd, __unused int argc, const __unused char **argv)
139{
140	struct flock fl1, fl2;
141
142	memset(&fl1, 1, sizeof(fl1));
143	fl1.l_type = F_WRLCK;
144	fl1.l_whence = SEEK_SET;
145	fl2 = fl1;
146
147	if (fcntl(fd, F_GETLK, &fl1) < 0)
148		err(1, "F_GETLK");
149
150	printf("1 - F_GETLK on unlocked region: ");
151	FAIL(fl1.l_start != fl2.l_start);
152	FAIL(fl1.l_len != fl2.l_len);
153	FAIL(fl1.l_pid != fl2.l_pid);
154	FAIL(fl1.l_type != F_UNLCK);
155	FAIL(fl1.l_whence != fl2.l_whence);
156#ifdef HAVE_SYSID
157	FAIL(fl1.l_sysid != fl2.l_sysid);
158#endif
159
160	SUCCEED;
161}
162
163/*
164 * Test 2 - F_SETLK on locked region
165 *
166 * If a shared or exclusive lock cannot be set, fcntl returns
167 * immediately with EACCES or EAGAIN.
168 */
169static int
170test2(int fd, __unused int argc, const __unused char **argv)
171{
172	/*
173	 * We create a child process to hold the lock which we will
174	 * test. We use a pipe to communicate with the child.
175	 */
176	int pid;
177	int pfd[2];
178	struct flock fl;
179	char ch;
180	int res;
181
182	if (pipe(pfd) < 0)
183		err(1, "pipe");
184
185	fl.l_start = 0;
186	fl.l_len = 0;
187	fl.l_type = F_WRLCK;
188	fl.l_whence = SEEK_SET;
189
190	pid = fork();
191	if (pid < 0)
192		err(1, "fork");
193
194	if (pid == 0) {
195		/*
196		 * We are the child. We set a write lock and then
197		 * write one byte back to the parent to tell it. The
198		 * parent will kill us when its done.
199		 */
200		if (fcntl(fd, F_SETLK, &fl) < 0)
201			err(1, "F_SETLK (child)");
202		if (write(pfd[1], "a", 1) < 0)
203			err(1, "writing to pipe (child)");
204		pause();
205		exit(0);
206	}
207
208	/*
209	 * Wait until the child has set its lock and then perform the
210	 * test.
211	 */
212	if (read(pfd[0], &ch, 1) != 1)
213		err(1, "reading from pipe (child)");
214
215	/*
216	 * fcntl should return -1 with errno set to either EACCES or
217	 * EAGAIN.
218	 */
219	printf("2 - F_SETLK on locked region: ");
220	res = fcntl(fd, F_SETLK, &fl);
221	kill(pid, SIGTERM);
222	safe_waitpid(pid);
223	close(pfd[0]);
224	close(pfd[1]);
225	FAIL(res == 0);
226	FAIL(errno != EACCES && errno != EAGAIN);
227
228	SUCCEED;
229}
230
231/*
232 * Test 3 - F_SETLKW on locked region
233 *
234 * If a shared or exclusive lock is blocked by other locks, the
235 * process waits until the request can be satisfied.
236 *
237 * XXX this test hangs on FreeBSD NFS filesystems due to limitations
238 * in FreeBSD's client (and server) lockd implementation.
239 */
240static int
241test3(int fd, __unused int argc, const __unused char **argv)
242{
243	/*
244	 * We create a child process to hold the lock which we will
245	 * test. We use a pipe to communicate with the child.
246	 */
247	int pid;
248	int pfd[2];
249	struct flock fl;
250	char ch;
251	int res;
252
253	if (pipe(pfd) < 0)
254		err(1, "pipe");
255
256	fl.l_start = 0;
257	fl.l_len = 0;
258	fl.l_type = F_WRLCK;
259	fl.l_whence = SEEK_SET;
260
261	pid = fork();
262	if (pid < 0)
263		err(1, "fork");
264
265	if (pid == 0) {
266		/*
267		 * We are the child. We set a write lock and then
268		 * write one byte back to the parent to tell it. The
269		 * parent will kill us when its done.
270		 */
271		if (fcntl(fd, F_SETLK, &fl) < 0)
272			err(1, "F_SETLK (child)");
273		if (write(pfd[1], "a", 1) < 0)
274			err(1, "writing to pipe (child)");
275		pause();
276		exit(0);
277	}
278
279	/*
280	 * Wait until the child has set its lock and then perform the
281	 * test.
282	 */
283	if (read(pfd[0], &ch, 1) != 1)
284		err(1, "reading from pipe (child)");
285
286	/*
287	 * fcntl should wait until the alarm and then return -1 with
288	 * errno set to EINTR.
289	 */
290	printf("3 - F_SETLKW on locked region: ");
291
292	alarm(1);
293
294	res = fcntl(fd, F_SETLKW, &fl);
295	kill(pid, SIGTERM);
296	safe_waitpid(pid);
297	close(pfd[0]);
298	close(pfd[1]);
299	FAIL(res == 0);
300	FAIL(errno != EINTR);
301
302	SUCCEED;
303}
304
305/*
306 * Test 4 - F_GETLK on locked region
307 *
308 * Get the first lock that blocks the lock.
309 */
310static int
311test4(int fd, __unused int argc, const __unused char **argv)
312{
313	/*
314	 * We create a child process to hold the lock which we will
315	 * test. We use a pipe to communicate with the child.
316	 */
317	int pid;
318	int pfd[2];
319	struct flock fl;
320	char ch;
321
322	if (pipe(pfd) < 0)
323		err(1, "pipe");
324
325	fl.l_start = 0;
326	fl.l_len = 99;
327	fl.l_type = F_WRLCK;
328	fl.l_whence = SEEK_SET;
329
330	pid = fork();
331	if (pid < 0)
332		err(1, "fork");
333
334	if (pid == 0) {
335		/*
336		 * We are the child. We set a write lock and then
337		 * write one byte back to the parent to tell it. The
338		 * parent will kill us when its done.
339		 */
340		if (fcntl(fd, F_SETLK, &fl) < 0)
341			err(1, "F_SETLK (child)");
342		if (write(pfd[1], "a", 1) < 0)
343			err(1, "writing to pipe (child)");
344		pause();
345		exit(0);
346	}
347
348	/*
349	 * Wait until the child has set its lock and then perform the
350	 * test.
351	 */
352	if (read(pfd[0], &ch, 1) != 1)
353		err(1, "reading from pipe (child)");
354
355	/*
356	 * fcntl should return a lock structure reflecting the lock we
357	 * made in the child process.
358	 */
359	if (fcntl(fd, F_GETLK, &fl) < 0)
360		err(1, "F_GETLK");
361
362	printf("4 - F_GETLK on locked region: ");
363	FAIL(fl.l_start != 0);
364	FAIL(fl.l_len != 99);
365	FAIL(fl.l_type != F_WRLCK);
366	FAIL(fl.l_pid != pid);
367#ifdef HAVE_SYSID
368	FAIL(fl.l_sysid != 0);
369#endif
370
371	kill(pid, SIGTERM);
372	safe_waitpid(pid);
373	close(pfd[0]);
374	close(pfd[1]);
375
376	SUCCEED;
377}
378
379/*
380 * Test 5 - F_SETLKW simple deadlock
381 *
382 * If a blocking shared lock request would cause a deadlock (i.e. the
383 * lock request is blocked by a process which is itself blocked on a
384 * lock currently owned by the process making the new request),
385 * EDEADLK is returned.
386 */
387static int
388test5(int fd, __unused int argc, const __unused char **argv)
389{
390	/*
391	 * We create a child process to hold the lock which we will
392	 * test. Because our test relies on the child process being
393	 * blocked on the parent's lock, we can't easily use a pipe to
394	 * synchronize so we just sleep in the parent to given the
395	 * child a chance to setup.
396	 *
397	 * To create the deadlock condition, we arrange for the parent
398	 * to lock the first byte of the file and the child to lock
399	 * the second byte.  After locking the second byte, the child
400	 * will attempt to lock the first byte of the file, and
401	 * block. The parent will then attempt to lock the second byte
402	 * (owned by the child) which should cause deadlock.
403	 */
404	int pid;
405	struct flock fl;
406	int res;
407
408	/*
409	 * Lock the first byte in the parent.
410	 */
411	fl.l_start = 0;
412	fl.l_len = 1;
413	fl.l_type = F_WRLCK;
414	fl.l_whence = SEEK_SET;
415	if (fcntl(fd, F_SETLK, &fl) < 0)
416		err(1, "F_SETLK 1 (parent)");
417
418	pid = fork();
419	if (pid < 0)
420		err(1, "fork");
421
422	if (pid == 0) {
423		/*
424		 * Lock the second byte in the child and then block on
425		 * the parent's lock.
426		 */
427		fl.l_start = 1;
428		if (fcntl(fd, F_SETLK, &fl) < 0)
429			err(1, "F_SETLK (child)");
430		fl.l_start = 0;
431		if (fcntl(fd, F_SETLKW, &fl) < 0)
432			err(1, "F_SETLKW (child)");
433		exit(0);
434	}
435
436	/*
437	 * Wait until the child has set its lock and then perform the
438	 * test.
439	 */
440	sleep(1);
441
442	/*
443	 * fcntl should immediately return -1 with errno set to
444	 * EDEADLK. If the alarm fires, we failed to detect the
445	 * deadlock.
446	 */
447	alarm(1);
448	printf("5 - F_SETLKW simple deadlock: ");
449
450	fl.l_start = 1;
451	res = fcntl(fd, F_SETLKW, &fl);
452	kill(pid, SIGTERM);
453	safe_waitpid(pid);
454
455	FAIL(res == 0);
456	FAIL(errno != EDEADLK);
457
458	fl.l_start = 0;
459	fl.l_len = 0;
460	fl.l_type = F_UNLCK;
461	if (fcntl(fd, F_SETLK, &fl) < 0)
462		err(1, "F_UNLCK");
463
464	/*
465	 * Cancel the alarm to avoid confusing later tests.
466	 */
467	alarm(0);
468
469	SUCCEED;
470}
471
472/*
473 * Test 6 - F_SETLKW complex deadlock.
474 *
475 * This test involves three process, P, C1 and C2. We set things up so
476 * that P locks byte zero, C1 locks byte 1 and C2 locks byte 2. We
477 * also block C2 by attempting to lock byte zero. Lastly, P attempts
478 * to lock a range including byte 1 and 2. This represents a deadlock
479 * (due to C2's blocking attempt to lock byte zero).
480 */
481static int
482test6(int fd, __unused int argc, const __unused char **argv)
483{
484	/*
485	 * Because our test relies on the child process being blocked
486	 * on the parent's lock, we can't easily use a pipe to
487	 * synchronize so we just sleep in the parent to given the
488	 * children a chance to setup.
489	 */
490	int pid1, pid2;
491	struct flock fl;
492	int res;
493
494	/*
495	 * Lock the first byte in the parent.
496	 */
497	fl.l_start = 0;
498	fl.l_len = 1;
499	fl.l_type = F_WRLCK;
500	fl.l_whence = SEEK_SET;
501	if (fcntl(fd, F_SETLK, &fl) < 0)
502		err(1, "F_SETLK 1 (parent)");
503
504	pid1 = fork();
505	if (pid1 < 0)
506		err(1, "fork");
507
508	if (pid1 == 0) {
509		/*
510		 * C1
511		 * Lock the second byte in the child and then sleep
512		 */
513		fl.l_start = 1;
514		if (fcntl(fd, F_SETLK, &fl) < 0)
515			err(1, "F_SETLK (child1)");
516		pause();
517		exit(0);
518	}
519
520	pid2 = fork();
521	if (pid2 < 0)
522		err(1, "fork");
523
524	if (pid2 == 0) {
525		/*
526		 * C2
527		 * Lock the third byte in the child and then block on
528		 * the parent's lock.
529		 */
530		fl.l_start = 2;
531		if (fcntl(fd, F_SETLK, &fl) < 0)
532			err(1, "F_SETLK (child2)");
533		fl.l_start = 0;
534		if (fcntl(fd, F_SETLKW, &fl) < 0)
535			err(1, "F_SETLKW (child2)");
536		exit(0);
537	}
538
539	/*
540	 * Wait until the children have set their locks and then
541	 * perform the test.
542	 */
543	sleep(1);
544
545	/*
546	 * fcntl should immediately return -1 with errno set to
547	 * EDEADLK. If the alarm fires, we failed to detect the
548	 * deadlock.
549	 */
550	alarm(1);
551	printf("6 - F_SETLKW complex deadlock: ");
552
553	fl.l_start = 1;
554	fl.l_len = 2;
555	res = fcntl(fd, F_SETLKW, &fl);
556	kill(pid1, SIGTERM);
557	safe_waitpid(pid1);
558	kill(pid2, SIGTERM);
559	safe_waitpid(pid2);
560
561	fl.l_start = 0;
562	fl.l_len = 0;
563	fl.l_type = F_UNLCK;
564	if (fcntl(fd, F_SETLK, &fl) < 0)
565		err(1, "F_UNLCK");
566
567	FAIL(res == 0);
568	FAIL(errno != EDEADLK);
569
570	/*
571	 * Cancel the alarm to avoid confusing later tests.
572	 */
573	alarm(0);
574
575	SUCCEED;
576}
577
578/*
579 * Test 7 - F_SETLK shared lock on exclusive locked region
580 *
581 * If a shared or exclusive lock cannot be set, fcntl returns
582 * immediately with EACCES or EAGAIN.
583 */
584static int
585test7(int fd, __unused int argc, const __unused char **argv)
586{
587	/*
588	 * We create a child process to hold the lock which we will
589	 * test. We use a pipe to communicate with the child.
590	 */
591	int pid;
592	int pfd[2];
593	struct flock fl;
594	char ch;
595	int res;
596
597	if (pipe(pfd) < 0)
598		err(1, "pipe");
599
600	fl.l_start = 0;
601	fl.l_len = 0;
602	fl.l_type = F_WRLCK;
603	fl.l_whence = SEEK_SET;
604
605	pid = fork();
606	if (pid < 0)
607		err(1, "fork");
608
609	if (pid == 0) {
610		/*
611		 * We are the child. We set a write lock and then
612		 * write one byte back to the parent to tell it. The
613		 * parent will kill us when its done.
614		 */
615		if (fcntl(fd, F_SETLK, &fl) < 0)
616			err(1, "F_SETLK (child)");
617		if (write(pfd[1], "a", 1) < 0)
618			err(1, "writing to pipe (child)");
619		pause();
620		exit(0);
621	}
622
623	/*
624	 * Wait until the child has set its lock and then perform the
625	 * test.
626	 */
627	if (read(pfd[0], &ch, 1) != 1)
628		err(1, "reading from pipe (child)");
629
630	/*
631	 * fcntl should wait until the alarm and then return -1 with
632	 * errno set to EINTR.
633	 */
634	printf("7 - F_SETLK shared lock on exclusive locked region: ");
635
636	fl.l_type = F_RDLCK;
637	res = fcntl(fd, F_SETLK, &fl);
638	kill(pid, SIGTERM);
639	safe_waitpid(pid);
640	close(pfd[0]);
641	close(pfd[1]);
642
643	FAIL(res == 0);
644	FAIL(errno != EACCES && errno != EAGAIN);
645
646	SUCCEED;
647}
648
649/*
650 * Test 8 - F_SETLK shared lock on share locked region
651 *
652 * When a shared lock is set on a segment of a file, other processes
653 * shall be able to set shared locks on that segment or a portion of
654 * it.
655 */
656static int
657test8(int fd, __unused int argc, const __unused char **argv)
658{
659	/*
660	 * We create a child process to hold the lock which we will
661	 * test. We use a pipe to communicate with the child.
662	 */
663	int pid;
664	int pfd[2];
665	struct flock fl;
666	char ch;
667	int res;
668
669	if (pipe(pfd) < 0)
670		err(1, "pipe");
671
672	fl.l_start = 0;
673	fl.l_len = 0;
674	fl.l_type = F_RDLCK;
675	fl.l_whence = SEEK_SET;
676
677	pid = fork();
678	if (pid < 0)
679		err(1, "fork");
680
681	if (pid == 0) {
682		/*
683		 * We are the child. We set a write lock and then
684		 * write one byte back to the parent to tell it. The
685		 * parent will kill us when its done.
686		 */
687		if (fcntl(fd, F_SETLK, &fl) < 0)
688			err(1, "F_SETLK (child)");
689		if (write(pfd[1], "a", 1) < 0)
690			err(1, "writing to pipe (child)");
691		pause();
692		exit(0);
693	}
694
695	/*
696	 * Wait until the child has set its lock and then perform the
697	 * test.
698	 */
699	if (read(pfd[0], &ch, 1) != 1)
700		err(1, "reading from pipe (child)");
701
702	/*
703	 * fcntl should wait until the alarm and then return -1 with
704	 * errno set to EINTR.
705	 */
706	printf("8 - F_SETLK shared lock on share locked region: ");
707
708	fl.l_type = F_RDLCK;
709	res = fcntl(fd, F_SETLK, &fl);
710
711	kill(pid, SIGTERM);
712	safe_waitpid(pid);
713	close(pfd[0]);
714	close(pfd[1]);
715
716	fl.l_start = 0;
717	fl.l_len = 0;
718	fl.l_type = F_UNLCK;
719	if (fcntl(fd, F_SETLK, &fl) < 0)
720		err(1, "F_UNLCK");
721
722	FAIL(res != 0);
723
724	SUCCEED;
725}
726
727/*
728 * Test 9 - F_SETLK exclusive lock on share locked region
729 *
730 * If a shared or exclusive lock cannot be set, fcntl returns
731 * immediately with EACCES or EAGAIN.
732 */
733static int
734test9(int fd, __unused int argc, const __unused char **argv)
735{
736	/*
737	 * We create a child process to hold the lock which we will
738	 * test. We use a pipe to communicate with the child.
739	 */
740	int pid;
741	int pfd[2];
742	struct flock fl;
743	char ch;
744	int res;
745
746	if (pipe(pfd) < 0)
747		err(1, "pipe");
748
749	fl.l_start = 0;
750	fl.l_len = 0;
751	fl.l_type = F_RDLCK;
752	fl.l_whence = SEEK_SET;
753
754	pid = fork();
755	if (pid < 0)
756		err(1, "fork");
757
758	if (pid == 0) {
759		/*
760		 * We are the child. We set a write lock and then
761		 * write one byte back to the parent to tell it. The
762		 * parent will kill us when its done.
763		 */
764		if (fcntl(fd, F_SETLK, &fl) < 0)
765			err(1, "F_SETLK (child)");
766		if (write(pfd[1], "a", 1) < 0)
767			err(1, "writing to pipe (child)");
768		pause();
769		exit(0);
770	}
771
772	/*
773	 * Wait until the child has set its lock and then perform the
774	 * test.
775	 */
776	if (read(pfd[0], &ch, 1) != 1)
777		err(1, "reading from pipe (child)");
778
779	/*
780	 * fcntl should wait until the alarm and then return -1 with
781	 * errno set to EINTR.
782	 */
783	printf("9 - F_SETLK exclusive lock on share locked region: ");
784
785	fl.l_type = F_WRLCK;
786	res = fcntl(fd, F_SETLK, &fl);
787	kill(pid, SIGTERM);
788	safe_waitpid(pid);
789	close(pfd[0]);
790	close(pfd[1]);
791
792	FAIL(res == 0);
793	FAIL(errno != EACCES && errno != EAGAIN);
794
795	SUCCEED;
796}
797
798/*
799 * Test 10 - trying to set bogus pid or sysid values
800 *
801 * The l_pid and l_sysid fields are only used with F_GETLK to return
802 * the process ID of the process holding a blocking lock and the
803 * system ID of the system that owns that process
804 */
805static int
806test10(int fd, __unused int argc, const __unused char **argv)
807{
808	/*
809	 * We create a child process to hold the lock which we will
810	 * test. We use a pipe to communicate with the child.
811	 */
812	int pid;
813	int pfd[2];
814	struct flock fl;
815	char ch;
816
817	if (pipe(pfd) < 0)
818		err(1, "pipe");
819
820	fl.l_start = 0;
821	fl.l_len = 0;
822	fl.l_type = F_WRLCK;
823	fl.l_whence = SEEK_SET;
824	fl.l_pid = 9999;
825#ifdef HAVE_SYSID
826	fl.l_sysid = 9999;
827#endif
828
829	pid = fork();
830	if (pid < 0)
831		err(1, "fork");
832
833	if (pid == 0) {
834		/*
835		 * We are the child. We set a write lock and then
836		 * write one byte back to the parent to tell it. The
837		 * parent will kill us when its done.
838		 */
839		if (fcntl(fd, F_SETLK, &fl) < 0)
840			err(1, "F_SETLK (child)");
841		if (write(pfd[1], "a", 1) < 0)
842			err(1, "writing to pipe (child)");
843		pause();
844		exit(0);
845	}
846
847	/*
848	 * Wait until the child has set its lock and then perform the
849	 * test.
850	 */
851	if (read(pfd[0], &ch, 1) != 1)
852		err(1, "reading from pipe (child)");
853
854	printf("10 - trying to set bogus pid or sysid values: ");
855
856	if (fcntl(fd, F_GETLK, &fl) < 0)
857		err(1, "F_GETLK");
858
859	kill(pid, SIGTERM);
860	safe_waitpid(pid);
861	close(pfd[0]);
862	close(pfd[1]);
863
864	FAIL(fl.l_pid != pid);
865#ifdef HAVE_SYSID
866	FAIL(fl.l_sysid != 0);
867#endif
868
869	SUCCEED;
870}
871
872/*
873 * Test 11 - remote locks
874 *
875 * XXX temporary interface which will be removed when the kernel lockd
876 * is added.
877 */
878static int
879test11(int fd, __unused int argc, const __unused char **argv)
880{
881#ifdef F_SETLK_REMOTE
882	struct flock fl;
883	int res;
884
885	if (geteuid() != 0)
886		return 0;
887
888	fl.l_start = 0;
889	fl.l_len = 0;
890	fl.l_type = F_WRLCK;
891	fl.l_whence = SEEK_SET;
892	fl.l_pid = 9999;
893	fl.l_sysid = 1001;
894
895	printf("11 - remote locks: ");
896
897	res = fcntl(fd, F_SETLK_REMOTE, &fl);
898	FAIL(res != 0);
899
900	fl.l_sysid = 1002;
901	res = fcntl(fd, F_SETLK_REMOTE, &fl);
902	FAIL(res == 0);
903	FAIL(errno != EACCES && errno != EAGAIN);
904
905	res = fcntl(fd, F_GETLK, &fl);
906	FAIL(res != 0);
907	FAIL(fl.l_pid != 9999);
908	FAIL(fl.l_sysid != 1001);
909
910	fl.l_type = F_UNLCK;
911	fl.l_sysid = 1001;
912	fl.l_start = 0;
913	fl.l_len = 0;
914	res = fcntl(fd, F_SETLK_REMOTE, &fl);
915	FAIL(res != 0);
916
917	fl.l_pid = 1234;
918	fl.l_sysid = 1001;
919	fl.l_start = 0;
920	fl.l_len = 1;
921	fl.l_whence = SEEK_SET;
922	fl.l_type = F_RDLCK;
923	res = fcntl(fd, F_SETLK_REMOTE, &fl);
924	FAIL(res != 0);
925
926	fl.l_sysid = 1002;
927	res = fcntl(fd, F_SETLK_REMOTE, &fl);
928	FAIL(res != 0);
929
930	fl.l_type = F_UNLCKSYS;
931	fl.l_sysid = 1001;
932	res = fcntl(fd, F_SETLK_REMOTE, &fl);
933	FAIL(res != 0);
934
935	fl.l_type = F_WRLCK;
936	res = fcntl(fd, F_GETLK, &fl);
937	FAIL(res != 0);
938	FAIL(fl.l_pid != 1234);
939	FAIL(fl.l_sysid != 1002);
940
941	fl.l_type = F_UNLCKSYS;
942	fl.l_sysid = 1002;
943	res = fcntl(fd, F_SETLK_REMOTE, &fl);
944	FAIL(res != 0);
945
946	SUCCEED;
947#else
948	return 0;
949#endif
950}
951
952/*
953 * Test 12 - F_SETLKW on locked region which is then unlocked
954 *
955 * If a shared or exclusive lock is blocked by other locks, the
956 * process waits until the request can be satisfied.
957 */
958static int
959test12(int fd, __unused int argc, const __unused char **argv)
960{
961	/*
962	 * We create a child process to hold the lock which we will
963	 * test. We use a pipe to communicate with the child.
964	 */
965	int pid;
966	int pfd[2];
967	struct flock fl;
968	char ch;
969	int res;
970
971	if (pipe(pfd) < 0)
972		err(1, "pipe");
973
974	fl.l_start = 0;
975	fl.l_len = 0;
976	fl.l_type = F_WRLCK;
977	fl.l_whence = SEEK_SET;
978
979	pid = fork();
980	if (pid < 0)
981		err(1, "fork");
982
983	if (pid == 0) {
984		/*
985		 * We are the child. We set a write lock and then
986		 * write one byte back to the parent to tell it. The
987		 * parent will kill us when its done.
988		 */
989		if (fcntl(fd, F_SETLK, &fl) < 0)
990			err(1, "F_SETLK (child)");
991		if (write(pfd[1], "a", 1) < 0)
992			err(1, "writing to pipe (child)");
993
994		sleep(1);
995		exit(0);
996	}
997
998	/*
999	 * Wait until the child has set its lock and then perform the
1000	 * test.
1001	 */
1002	if (read(pfd[0], &ch, 1) != 1)
1003		err(1, "reading from pipe (child)");
1004
1005	/*
1006	 * fcntl should wait until the alarm and then return -1 with
1007	 * errno set to EINTR.
1008	 */
1009	printf("12 - F_SETLKW on locked region which is then unlocked: ");
1010
1011	//alarm(1);
1012
1013	res = fcntl(fd, F_SETLKW, &fl);
1014	kill(pid, SIGTERM);
1015	safe_waitpid(pid);
1016	close(pfd[0]);
1017	close(pfd[1]);
1018	FAIL(res != 0);
1019
1020	fl.l_start = 0;
1021	fl.l_len = 0;
1022	fl.l_type = F_UNLCK;
1023	if (fcntl(fd, F_SETLK, &fl) < 0)
1024		err(1, "F_UNLCK");
1025
1026	SUCCEED;
1027}
1028
1029/*
1030 * Test 13 - F_SETLKW on locked region, race with owner
1031 *
1032 * If a shared or exclusive lock is blocked by other locks, the
1033 * process waits until the request can be satisfied.
1034 */
1035static int
1036test13(int fd, __unused int argc, const __unused char **argv)
1037{
1038	/*
1039	 * We create a child process to hold the lock which we will
1040	 * test. We use a pipe to communicate with the child.
1041	 */
1042	int i;
1043	int pid;
1044	int pfd[2];
1045	struct flock fl;
1046	char ch;
1047	int res;
1048	struct itimerval itv;
1049
1050	printf("13 - F_SETLKW on locked region, race with owner: ");
1051	fflush(stdout);
1052
1053	for (i = 0; i < 100; i++) {
1054		if (pipe(pfd) < 0)
1055			err(1, "pipe");
1056
1057		fl.l_start = 0;
1058		fl.l_len = 0;
1059		fl.l_type = F_WRLCK;
1060		fl.l_whence = SEEK_SET;
1061
1062		pid = fork();
1063		if (pid < 0)
1064			err(1, "fork");
1065
1066		if (pid == 0) {
1067			/*
1068			 * We are the child. We set a write lock and then
1069			 * write one byte back to the parent to tell it. The
1070			 * parent will kill us when its done.
1071			 */
1072			if (fcntl(fd, F_SETLK, &fl) < 0)
1073				err(1, "F_SETLK (child)");
1074			if (write(pfd[1], "a", 1) < 0)
1075				err(1, "writing to pipe (child)");
1076
1077			usleep(1);
1078			exit(0);
1079		}
1080
1081		/*
1082		 * Wait until the child has set its lock and then perform the
1083		 * test.
1084		 */
1085		while (read(pfd[0], &ch, 1) != 1) {
1086			if (errno == EINTR)
1087				continue;
1088			err(1, "reading from pipe (child)");
1089		}
1090
1091		/*
1092		 * fcntl should wait until the alarm and then return -1 with
1093		 * errno set to EINTR.
1094		 */
1095		itv.it_interval.tv_sec = 0;
1096		itv.it_interval.tv_usec = 0;
1097		itv.it_value.tv_sec = 0;
1098		itv.it_value.tv_usec = 2;
1099		setitimer(ITIMER_REAL, &itv, NULL);
1100
1101		res = fcntl(fd, F_SETLKW, &fl);
1102		kill(pid, SIGTERM);
1103		safe_waitpid(pid);
1104		close(pfd[0]);
1105		close(pfd[1]);
1106		FAIL(!(res == 0 || (res == -1 && errno == EINTR)));
1107
1108		fl.l_start = 0;
1109		fl.l_len = 0;
1110		fl.l_type = F_UNLCK;
1111		if (fcntl(fd, F_SETLK, &fl) < 0)
1112			err(1, "F_UNLCK");
1113	}
1114	SUCCEED;
1115}
1116
1117/*
1118 * Test 14 - soak test
1119 */
1120static int
1121test14(int fd, int argc, const char **argv)
1122{
1123#define CHILD_COUNT 20
1124	/*
1125	 * We create a set of child processes and let each one run
1126	 * through a random sequence of locks and unlocks.
1127	 */
1128	int i, j, id, id_base;
1129	int pids[CHILD_COUNT], pid;
1130	char buf[128];
1131	char tbuf[128];
1132	int map[128];
1133	char outbuf[512];
1134	struct flock fl;
1135	struct itimerval itv;
1136	int status;
1137
1138	id_base = 0;
1139	if (argc >= 2)
1140		id_base = strtol(argv[1], NULL, 0);
1141
1142	printf("14 - soak test: ");
1143	fflush(stdout);
1144
1145	for (i = 0; i < 128; i++)
1146		map[i] = F_UNLCK;
1147
1148	for (i = 0; i < CHILD_COUNT; i++) {
1149
1150		pid = fork();
1151		if (pid < 0)
1152			err(1, "fork");
1153		if (pid) {
1154			/*
1155			 * Parent - record the pid and continue.
1156			 */
1157			pids[i] = pid;
1158			continue;
1159		}
1160
1161		/*
1162		 * Child - do some work and exit.
1163		 */
1164		id = id_base + i;
1165		srandom(getpid());
1166
1167		for (j = 0; j < 50; j++) {
1168			int start, end, len;
1169			int set, wrlock;
1170
1171			do {
1172				start = random() & 127;
1173				end = random() & 127;
1174			} while (end <= start);
1175
1176			set = random() & 1;
1177			wrlock = random() & 1;
1178
1179			len = end - start;
1180			fl.l_start = start;
1181			fl.l_len = len;
1182			fl.l_whence = SEEK_SET;
1183			if (set)
1184				fl.l_type = wrlock ? F_WRLCK : F_RDLCK;
1185			else
1186				fl.l_type = F_UNLCK;
1187
1188			itv.it_interval.tv_sec = 0;
1189			itv.it_interval.tv_usec = 0;
1190			itv.it_value.tv_sec = 0;
1191			itv.it_value.tv_usec = 3000;
1192			setitimer(ITIMER_REAL, &itv, NULL);
1193
1194			if (fcntl(fd, F_SETLKW, &fl) < 0) {
1195				if (errno == EDEADLK || errno == EINTR) {
1196					if (verbose) {
1197						snprintf(outbuf, sizeof(outbuf),
1198						    "%d[%d]: %s [%d .. %d] %s\n",
1199						    id, j,
1200						    set ? (wrlock ? "write lock"
1201							: "read lock")
1202						    : "unlock", start, end,
1203						    errno == EDEADLK
1204						    ? "deadlock"
1205						    : "interrupted");
1206						write(1, outbuf,
1207						    strlen(outbuf));
1208					}
1209					continue;
1210				} else {
1211					perror("fcntl");
1212				}
1213			}
1214
1215			itv.it_interval.tv_sec = 0;
1216			itv.it_interval.tv_usec = 0;
1217			itv.it_value.tv_sec = 0;
1218			itv.it_value.tv_usec = 0;
1219			setitimer(ITIMER_REAL, &itv, NULL);
1220
1221			if (verbose) {
1222				snprintf(outbuf, sizeof(outbuf),
1223				    "%d[%d]: %s [%d .. %d] succeeded\n",
1224				    id, j,
1225				    set ? (wrlock ? "write lock" : "read lock")
1226				    : "unlock", start, end);
1227				write(1, outbuf, strlen(outbuf));
1228			}
1229
1230			if (set) {
1231				if (wrlock) {
1232					/*
1233					 * We got a write lock - write
1234					 * our ID to each byte that we
1235					 * managed to claim.
1236					 */
1237					for (i = start; i < end; i++)
1238						map[i] = F_WRLCK;
1239					memset(&buf[start], id, len);
1240					if (pwrite(fd, &buf[start], len,
1241						start) != len) {
1242						printf("%d: short write\n", id);
1243						exit(1);
1244					}
1245				} else {
1246					/*
1247					 * We got a read lock - read
1248					 * the bytes which we claimed
1249					 * so that we can check that
1250					 * they don't change
1251					 * unexpectedly.
1252					 */
1253					for (i = start; i < end; i++)
1254						map[i] = F_RDLCK;
1255					if (pread(fd, &buf[start], len,
1256						start) != len) {
1257						printf("%d: short read\n", id);
1258						exit(1);
1259					}
1260				}
1261			} else {
1262				for (i = start; i < end; i++)
1263					map[i] = F_UNLCK;
1264			}
1265
1266			usleep(1000);
1267
1268			/*
1269			 * Read back the whole region so that we can
1270			 * check that all the bytes we have some kind
1271			 * of claim to have the correct value.
1272			 */
1273			if (pread(fd, tbuf, sizeof(tbuf), 0) != sizeof(tbuf)) {
1274				printf("%d: short read\n", id);
1275				exit(1);
1276			}
1277
1278			for (i = 0; i < 128; i++) {
1279				if (map[i] != F_UNLCK && buf[i] != tbuf[i]) {
1280					snprintf(outbuf, sizeof(outbuf),
1281					    "%d: byte %d expected %d, "
1282					    "got %d\n", id, i, buf[i], tbuf[i]);
1283					write(1, outbuf, strlen(outbuf));
1284					exit(1);
1285				}
1286			}
1287		}
1288		if (verbose)
1289			printf("%d[%d]: done\n", id, j);
1290
1291		exit(0);
1292	}
1293
1294	status = 0;
1295	for (i = 0; i < CHILD_COUNT; i++) {
1296		status += safe_waitpid(pids[i]);
1297	}
1298	if (status)
1299		FAIL(status != 0);
1300
1301	SUCCEED;
1302}
1303
1304/*
1305 * Test 15 - flock(2) semantcs
1306 *
1307 * When a lock holder has a shared lock and attempts to upgrade that
1308 * shared lock to exclusive, it must drop the shared lock before
1309 * blocking on the exclusive lock.
1310 *
1311 * To test this, we first arrange for two shared locks on the file,
1312 * and then attempt to upgrade one of them to exclusive. This should
1313 * drop one of the shared locks and block. We interrupt the blocking
1314 * lock request and examine the lock state of the file after dropping
1315 * the other shared lock - there should be no active locks at this
1316 * point.
1317 */
1318static int
1319test15(int fd, __unused int argc, const __unused char **argv)
1320{
1321#ifdef LOCK_EX
1322	/*
1323	 * We create a child process to hold the lock which we will
1324	 * test. We use a pipe to communicate with the child.
1325	 *
1326	 * Since we only have one file descriptors and lock ownership
1327	 * for flock(2) goes with the file descriptor, we use fcntl to
1328	 * set the child's shared lock.
1329	 */
1330	int pid;
1331	int pfd[2];
1332	int fd2;
1333	struct flock fl;
1334	char ch;
1335	int res;
1336
1337	if (pipe(pfd) < 0)
1338		err(1, "pipe");
1339
1340	pid = fork();
1341	if (pid < 0)
1342		err(1, "fork");
1343
1344	if (pid == 0) {
1345		/*
1346		 * We are the child. We set a shared lock and then
1347		 * write one byte back to the parent to tell it. The
1348		 * parent will kill us when its done.
1349		 */
1350		fl.l_start = 0;
1351		fl.l_len = 0;
1352		fl.l_type = F_RDLCK;
1353		fl.l_whence = SEEK_SET;
1354		if (fcntl(fd, F_SETLK, &fl) < 0)
1355			err(1, "fcntl(F_SETLK) (child)");
1356		if (write(pfd[1], "a", 1) < 0)
1357			err(1, "writing to pipe (child)");
1358		pause();
1359		exit(0);
1360	}
1361
1362	/*
1363	 * Wait until the child has set its lock and then perform the
1364	 * test.
1365	 */
1366	if (read(pfd[0], &ch, 1) != 1)
1367		err(1, "reading from pipe (child)");
1368
1369	fd2 = dup(fd);
1370	if (flock(fd, LOCK_SH) < 0)
1371		err(1, "flock shared");
1372
1373	/*
1374	 * flock should wait until the alarm and then return -1 with
1375	 * errno set to EINTR.
1376	 */
1377	printf("15 - flock(2) semantics: ");
1378
1379	alarm(1);
1380	flock(fd, LOCK_EX);
1381
1382	/*
1383	 * Kill the child to force it to drop its locks.
1384	 */
1385	kill(pid, SIGTERM);
1386	safe_waitpid(pid);
1387
1388	fl.l_start = 0;
1389	fl.l_len = 0;
1390	fl.l_type = F_WRLCK;
1391	fl.l_whence = SEEK_SET;
1392	res = fcntl(fd, F_GETLK, &fl);
1393
1394	close(pfd[0]);
1395	close(pfd[1]);
1396	FAIL(res != 0);
1397	FAIL(fl.l_type != F_UNLCK);
1398
1399	SUCCEED;
1400#else
1401	return 0;
1402#endif
1403}
1404
1405struct test_ctx {
1406	struct flock tc_fl;
1407	int tc_fd;
1408};
1409
1410static void *
1411test16_func(void *tc_in)
1412{
1413	uintptr_t error;
1414	struct test_ctx *tc = tc_in;
1415
1416	error = fcntl(tc->tc_fd, F_SETLKW, &tc->tc_fl);
1417
1418	pthread_exit((void *)error);
1419}
1420
1421#define THREADS 10
1422
1423/*
1424 * Test 16 - F_SETLKW from two threads
1425 *
1426 * If two threads within a process are blocked on a lock and the lock
1427 * is granted, make sure things are sane.
1428 */
1429static int
1430test16(int fd, __unused int argc, const __unused char **argv)
1431{
1432	/*
1433	 * We create a child process to hold the lock which we will
1434	 * test. We use a pipe to communicate with the child.
1435	 */
1436	int pid;
1437	int pfd[2];
1438	struct test_ctx tc = { .tc_fd = fd };
1439	char ch;
1440	int i;
1441	int error;
1442	pthread_t thr[THREADS];
1443
1444	if (pipe(pfd) < 0)
1445		err(1, "pipe");
1446
1447	tc.tc_fl.l_start = 0;
1448	tc.tc_fl.l_len = 0;
1449	tc.tc_fl.l_type = F_WRLCK;
1450	tc.tc_fl.l_whence = SEEK_SET;
1451
1452	pid = fork();
1453	if (pid < 0)
1454		err(1, "fork");
1455
1456	if (pid == 0) {
1457		/*
1458		 * We are the child. We set a write lock and then
1459		 * write one byte back to the parent to tell it. The
1460		 * parent will kill us when its done.
1461		 */
1462		if (fcntl(fd, F_SETLK, &tc.tc_fl) < 0)
1463			err(1, "F_SETLK (child)");
1464		if (write(pfd[1], "a", 1) < 0)
1465			err(1, "writing to pipe (child)");
1466		pause();
1467		exit(0);
1468	}
1469
1470	/*
1471	 * Wait until the child has set its lock and then perform the
1472	 * test.
1473	 */
1474	if (read(pfd[0], &ch, 1) != 1)
1475		err(1, "reading from pipe (child)");
1476
1477	/*
1478	 * fcntl should wait until the alarm and then return -1 with
1479	 * errno set to EINTR.
1480	 */
1481	printf("16 - F_SETLKW on locked region by two threads: ");
1482
1483	for (i = 0; i < THREADS; i++) {
1484		error = pthread_create(&thr[i], NULL, test16_func, &tc);
1485		if (error)
1486			err(1, "pthread_create");
1487	}
1488
1489	/*
1490	 * Sleep, then kill the child. This makes me a little sad, but it's
1491	 * tricky to tell whether the threads are all really blocked by this
1492	 * point.
1493	 */
1494	sleep(1);
1495	kill(pid, SIGTERM);
1496	safe_waitpid(pid);
1497	close(pfd[0]);
1498	close(pfd[1]);
1499
1500	for (i = 0; i < THREADS; i++) {
1501		void *res;
1502		error = pthread_join(thr[i], &res);
1503		if (error)
1504			err(1, "pthread_join");
1505		FAIL((uintptr_t)res != 0);
1506	}
1507
1508	SUCCEED;
1509}
1510
1511struct test {
1512	int (*testfn)(int, int, const char **);	/* function to perform the test */
1513	int num;		/* test number */
1514	int intr;		/* non-zero if the test interrupts a lock */
1515};
1516
1517struct test tests[] = {
1518	{	test1,		1,	0	},
1519	{	test2,		2,	0	},
1520	{	test3,		3,	1	},
1521	{	test4,		4,	0	},
1522	{	test5,		5,	1	},
1523	{	test6,		6,	1	},
1524	{	test7,		7,	0	},
1525	{	test8,		8,	0	},
1526	{	test9,		9,	0	},
1527	{	test10,		10,	0	},
1528	{	test11,		11,	1	},
1529	{	test12,		12,	0	},
1530	{	test13,		13,	1	},
1531	{	test14,		14,	0	},
1532	{	test15,		15,	1	},
1533	{	test16,		16,	1	},
1534};
1535int test_count = sizeof(tests) / sizeof(tests[0]);
1536
1537int
1538main(int argc, const char *argv[])
1539{
1540	int testnum;
1541	int fd;
1542	int nointr;
1543	int i;
1544	struct sigaction sa;
1545	int test_argc;
1546	const char **test_argv;
1547
1548	if (argc < 2) {
1549		errx(1, "usage: flock <directory> [test number] ...");
1550	}
1551
1552	fd = make_file(argv[1], 1024);
1553	if (argc >= 3) {
1554		testnum = strtol(argv[2], NULL, 0);
1555		test_argc = argc - 2;
1556		test_argv = argv + 2;
1557	} else {
1558		testnum = 0;
1559		test_argc = 0;
1560		test_argv = 0;
1561	}
1562
1563	sa.sa_handler = ignore_alarm;
1564	sigemptyset(&sa.sa_mask);
1565	sa.sa_flags = 0;
1566	sigaction(SIGALRM, &sa, 0);
1567
1568	nointr = 0;
1569#if defined(__FreeBSD__) && __FreeBSD_version < 800040
1570	{
1571		/*
1572		 * FreeBSD with userland NLM can't interrupt a blocked
1573		 * lock request on an NFS mounted filesystem.
1574		 */
1575		struct statfs st;
1576		fstatfs(fd, &st);
1577		nointr = !strcmp(st.f_fstypename, "nfs");
1578	}
1579#endif
1580
1581	for (i = 0; i < test_count; i++) {
1582		if (tests[i].intr && nointr)
1583			continue;
1584		if (!testnum || tests[i].num == testnum)
1585			tests[i].testfn(fd, test_argc, test_argv);
1586	}
1587
1588	return 0;
1589}
1590