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 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 108 ignore_alarm(int __unused sig) 109 { 110 } 111 112 static int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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