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