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