1 /* 2 * Copyright (c) 2015-2016 Cyril Hrubis <chrubis (at) suse.cz> 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include <stdio.h> 19 #include <stdarg.h> 20 #include <unistd.h> 21 #include <string.h> 22 #include <stdlib.h> 23 #include <errno.h> 24 #include <sys/mount.h> 25 #include <sys/types.h> 26 #include <sys/wait.h> 27 28 #define TST_NO_DEFAULT_MAIN 29 #include "tst_test.h" 30 #include "tst_device.h" 31 #include "lapi/futex.h" 32 #include "lapi/syscalls.h" 33 #include "tst_ansi_color.h" 34 #include "tst_safe_stdio.h" 35 #include "tst_timer_test.h" 36 #include "tst_clocks.h" 37 #include "tst_timer.h" 38 #include "tst_sys_conf.h" 39 40 #include "old_resource.h" 41 #include "old_device.h" 42 #include "old_tmpdir.h" 43 44 struct tst_test *tst_test; 45 46 static const char *tid; 47 static int iterations = 1; 48 static float duration = -1; 49 static pid_t main_pid, lib_pid; 50 static int mntpoint_mounted; 51 static struct timespec tst_start_time; /* valid only for test pid */ 52 53 struct results { 54 int passed; 55 int skipped; 56 int failed; 57 int warnings; 58 unsigned int timeout; 59 }; 60 61 static struct results *results; 62 63 static int ipc_fd; 64 65 extern void *tst_futexes; 66 extern unsigned int tst_max_futexes; 67 68 #define IPC_ENV_VAR "LTP_IPC_PATH" 69 70 static char ipc_path[1024]; 71 const char *tst_ipc_path = ipc_path; 72 73 static char shm_path[1024]; 74 75 int TST_ERR; 76 long TST_RET; 77 78 static void do_cleanup(void); 79 static void do_exit(int ret) __attribute__ ((noreturn)); 80 81 static void setup_ipc(void) 82 { 83 size_t size = getpagesize(); 84 85 if (access("/dev/shm", F_OK) == 0) { 86 snprintf(shm_path, sizeof(shm_path), "/dev/shm/ltp_%s_%d", 87 tid, getpid()); 88 } else { 89 char *tmpdir; 90 91 if (!tst_tmpdir_created()) 92 tst_tmpdir(); 93 94 tmpdir = tst_get_tmpdir(); 95 snprintf(shm_path, sizeof(shm_path), "%s/ltp_%s_%d", 96 tmpdir, tid, getpid()); 97 free(tmpdir); 98 } 99 100 ipc_fd = open(shm_path, O_CREAT | O_EXCL | O_RDWR, 0600); 101 if (ipc_fd < 0) 102 tst_brk(TBROK | TERRNO, "open(%s)", shm_path); 103 SAFE_CHMOD(shm_path, 0666); 104 105 SAFE_FTRUNCATE(ipc_fd, size); 106 107 results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc_fd, 0); 108 109 /* Checkpoints needs to be accessible from processes started by exec() */ 110 if (tst_test->needs_checkpoints || tst_test->child_needs_reinit) { 111 sprintf(ipc_path, IPC_ENV_VAR "=%s", shm_path); 112 putenv(ipc_path); 113 } else { 114 SAFE_UNLINK(shm_path); 115 } 116 117 SAFE_CLOSE(ipc_fd); 118 119 if (tst_test->needs_checkpoints) { 120 tst_futexes = (char*)results + sizeof(struct results); 121 tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); 122 } 123 } 124 125 static void cleanup_ipc(void) 126 { 127 size_t size = getpagesize(); 128 129 if (ipc_fd > 0 && close(ipc_fd)) 130 tst_res(TWARN | TERRNO, "close(ipc_fd) failed"); 131 132 if (shm_path[0] && !access(shm_path, F_OK) && unlink(shm_path)) 133 tst_res(TWARN | TERRNO, "unlink(%s) failed", shm_path); 134 135 if (results) { 136 msync((void*)results, size, MS_SYNC); 137 munmap((void*)results, size); 138 } 139 } 140 141 void tst_reinit(void) 142 { 143 const char *path = getenv(IPC_ENV_VAR); 144 size_t size = getpagesize(); 145 int fd; 146 147 if (!path) 148 tst_brk(TBROK, IPC_ENV_VAR" is not defined"); 149 150 if (access(path, F_OK)) 151 tst_brk(TBROK, "File %s does not exist!", path); 152 153 fd = SAFE_OPEN(path, O_RDWR); 154 155 results = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 156 tst_futexes = (char*)results + sizeof(struct results); 157 tst_max_futexes = (size - sizeof(struct results))/sizeof(futex_t); 158 159 SAFE_CLOSE(fd); 160 } 161 162 static void update_results(int ttype) 163 { 164 if (!results) 165 return; 166 167 switch (ttype) { 168 case TCONF: 169 tst_atomic_inc(&results->skipped); 170 break; 171 case TPASS: 172 tst_atomic_inc(&results->passed); 173 break; 174 case TWARN: 175 tst_atomic_inc(&results->warnings); 176 break; 177 case TFAIL: 178 tst_atomic_inc(&results->failed); 179 break; 180 } 181 } 182 183 static void print_result(const char *file, const int lineno, int ttype, 184 const char *fmt, va_list va) 185 { 186 char buf[1024]; 187 char *str = buf; 188 int ret, size = sizeof(buf), ssize; 189 const char *str_errno = NULL; 190 const char *res; 191 192 switch (TTYPE_RESULT(ttype)) { 193 case TPASS: 194 res = "PASS"; 195 break; 196 case TFAIL: 197 res = "FAIL"; 198 break; 199 case TBROK: 200 res = "BROK"; 201 break; 202 case TCONF: 203 res = "CONF"; 204 break; 205 case TWARN: 206 res = "WARN"; 207 break; 208 case TINFO: 209 res = "INFO"; 210 break; 211 default: 212 tst_brk(TBROK, "Invalid ttype value %i", ttype); 213 abort(); 214 } 215 216 if (ttype & TERRNO) 217 str_errno = tst_strerrno(errno); 218 219 if (ttype & TTERRNO) 220 str_errno = tst_strerrno(TST_ERR); 221 222 if (ttype & TRERRNO) { 223 ret = TST_RET < 0 ? -(int)TST_RET : (int)TST_RET; 224 str_errno = tst_strerrno(ret); 225 } 226 227 ret = snprintf(str, size, "%s:%i: ", file, lineno); 228 str += ret; 229 size -= ret; 230 231 if (tst_color_enabled(STDERR_FILENO)) 232 ret = snprintf(str, size, "%s%s: %s", tst_ttype2color(ttype), 233 res, ANSI_COLOR_RESET); 234 else 235 ret = snprintf(str, size, "%s: ", res); 236 str += ret; 237 size -= ret; 238 239 ssize = size - 2; 240 ret = vsnprintf(str, size, fmt, va); 241 str += MIN(ret, ssize); 242 size -= MIN(ret, ssize); 243 if (ret >= ssize) { 244 tst_res_(file, lineno, TWARN, 245 "Next message is too long and truncated:"); 246 } else if (str_errno) { 247 ssize = size - 2; 248 ret = snprintf(str, size, ": %s", str_errno); 249 str += MIN(ret, ssize); 250 size -= MIN(ret, ssize); 251 if (ret >= ssize) 252 tst_res_(file, lineno, TWARN, 253 "Next message is too long and truncated:"); 254 } 255 256 snprintf(str, size, "\n"); 257 258 fputs(buf, stderr); 259 } 260 261 void tst_vres_(const char *file, const int lineno, int ttype, 262 const char *fmt, va_list va) 263 { 264 print_result(file, lineno, ttype, fmt, va); 265 266 update_results(TTYPE_RESULT(ttype)); 267 } 268 269 void tst_vbrk_(const char *file, const int lineno, int ttype, 270 const char *fmt, va_list va); 271 272 static void (*tst_brk_handler)(const char *file, const int lineno, int ttype, 273 const char *fmt, va_list va) = tst_vbrk_; 274 275 static void tst_cvres(const char *file, const int lineno, int ttype, 276 const char *fmt, va_list va) 277 { 278 if (TTYPE_RESULT(ttype) == TBROK) { 279 ttype &= ~TTYPE_MASK; 280 ttype |= TWARN; 281 } 282 283 print_result(file, lineno, ttype, fmt, va); 284 update_results(TTYPE_RESULT(ttype)); 285 } 286 287 static void do_test_cleanup(void) 288 { 289 tst_brk_handler = tst_cvres; 290 291 if (tst_test->cleanup) 292 tst_test->cleanup(); 293 294 tst_brk_handler = tst_vbrk_; 295 } 296 297 void tst_vbrk_(const char *file, const int lineno, int ttype, 298 const char *fmt, va_list va) 299 { 300 print_result(file, lineno, ttype, fmt, va); 301 302 /* 303 * The getpid implementation in some C library versions may cause cloned 304 * test threads to show the same pid as their parent when CLONE_VM is 305 * specified but CLONE_THREAD is not. Use direct syscall to avoid 306 * cleanup running in the child. 307 */ 308 if (syscall(SYS_getpid) == main_pid) 309 do_test_cleanup(); 310 311 if (getpid() == lib_pid) 312 do_exit(TTYPE_RESULT(ttype)); 313 314 exit(TTYPE_RESULT(ttype)); 315 } 316 317 void tst_res_(const char *file, const int lineno, int ttype, 318 const char *fmt, ...) 319 { 320 va_list va; 321 322 va_start(va, fmt); 323 tst_vres_(file, lineno, ttype, fmt, va); 324 va_end(va); 325 } 326 327 void tst_brk_(const char *file, const int lineno, int ttype, 328 const char *fmt, ...) 329 { 330 va_list va; 331 332 va_start(va, fmt); 333 tst_brk_handler(file, lineno, ttype, fmt, va); 334 va_end(va); 335 } 336 337 static void check_child_status(pid_t pid, int status) 338 { 339 int ret; 340 341 if (WIFSIGNALED(status)) { 342 tst_brk(TBROK, "Child (%i) killed by signal %s", 343 pid, tst_strsig(WTERMSIG(status))); 344 } 345 346 if (!(WIFEXITED(status))) 347 tst_brk(TBROK, "Child (%i) exited abnormaly", pid); 348 349 ret = WEXITSTATUS(status); 350 switch (ret) { 351 case TPASS: 352 break; 353 case TBROK: 354 case TCONF: 355 tst_brk(ret, "Reported by child (%i)", pid); 356 break; 357 default: 358 tst_brk(TBROK, "Invalid child (%i) exit value %i", pid, ret); 359 } 360 } 361 362 void tst_reap_children(void) 363 { 364 int status; 365 pid_t pid; 366 367 for (;;) { 368 pid = wait(&status); 369 370 if (pid > 0) { 371 check_child_status(pid, status); 372 continue; 373 } 374 375 if (errno == ECHILD) 376 break; 377 378 if (errno == EINTR) 379 continue; 380 381 tst_brk(TBROK | TERRNO, "wait() failed"); 382 } 383 } 384 385 386 pid_t safe_fork(const char *filename, unsigned int lineno) 387 { 388 pid_t pid; 389 390 if (!tst_test->forks_child) 391 tst_brk(TBROK, "test.forks_child must be set!"); 392 393 tst_flush(); 394 395 pid = fork(); 396 if (pid < 0) 397 tst_brk_(filename, lineno, TBROK | TERRNO, "fork() failed"); 398 399 return pid; 400 } 401 402 static struct option { 403 char *optstr; 404 char *help; 405 } options[] = { 406 {"h", "-h Prints this help"}, 407 {"i:", "-i n Execute test n times"}, 408 {"I:", "-I x Execute test for n seconds"}, 409 {"C:", "-C ARG Run child process with ARG arguments (used internally)"}, 410 }; 411 412 static void print_help(void) 413 { 414 unsigned int i; 415 416 for (i = 0; i < ARRAY_SIZE(options); i++) 417 fprintf(stderr, "%s\n", options[i].help); 418 419 if (!tst_test->options) 420 return; 421 422 for (i = 0; tst_test->options[i].optstr; i++) 423 fprintf(stderr, "%s\n", tst_test->options[i].help); 424 } 425 426 static void check_option_collision(void) 427 { 428 unsigned int i, j; 429 struct tst_option *toptions = tst_test->options; 430 431 if (!toptions) 432 return; 433 434 for (i = 0; toptions[i].optstr; i++) { 435 for (j = 0; j < ARRAY_SIZE(options); j++) { 436 if (toptions[i].optstr[0] == options[j].optstr[0]) { 437 tst_brk(TBROK, "Option collision '%s'", 438 options[j].help); 439 } 440 } 441 } 442 } 443 444 static unsigned int count_options(void) 445 { 446 unsigned int i; 447 448 if (!tst_test->options) 449 return 0; 450 451 for (i = 0; tst_test->options[i].optstr; i++); 452 453 return i; 454 } 455 456 static void parse_topt(unsigned int topts_len, int opt, char *optarg) 457 { 458 unsigned int i; 459 struct tst_option *toptions = tst_test->options; 460 461 for (i = 0; i < topts_len; i++) { 462 if (toptions[i].optstr[0] == opt) 463 break; 464 } 465 466 if (i >= topts_len) 467 tst_brk(TBROK, "Invalid option '%c' (should not happen)", opt); 468 469 *(toptions[i].arg) = optarg ? optarg : ""; 470 } 471 472 /* see self_exec.c */ 473 #ifdef UCLINUX 474 extern char *child_args; 475 #endif 476 477 static void parse_opts(int argc, char *argv[]) 478 { 479 unsigned int i, topts_len = count_options(); 480 char optstr[2 * ARRAY_SIZE(options) + 2 * topts_len]; 481 int opt; 482 483 check_option_collision(); 484 485 optstr[0] = 0; 486 487 for (i = 0; i < ARRAY_SIZE(options); i++) 488 strcat(optstr, options[i].optstr); 489 490 for (i = 0; i < topts_len; i++) 491 strcat(optstr, tst_test->options[i].optstr); 492 493 while ((opt = getopt(argc, argv, optstr)) > 0) { 494 switch (opt) { 495 case '?': 496 print_help(); 497 tst_brk(TBROK, "Invalid option"); 498 break; 499 case 'h': 500 print_help(); 501 exit(0); 502 case 'i': 503 iterations = atoi(optarg); 504 break; 505 case 'I': 506 duration = atof(optarg); 507 break; 508 case 'C': 509 #ifdef UCLINUX 510 child_args = optarg; 511 #endif 512 break; 513 default: 514 parse_topt(topts_len, opt, optarg); 515 } 516 } 517 518 if (optind < argc) 519 tst_brk(TBROK, "Unexpected argument(s) '%s'...", argv[optind]); 520 } 521 522 int tst_parse_int(const char *str, int *val, int min, int max) 523 { 524 long rval; 525 526 if (!str) 527 return 0; 528 529 int ret = tst_parse_long(str, &rval, min, max); 530 531 if (ret) 532 return ret; 533 534 *val = (int)rval; 535 return 0; 536 } 537 538 int tst_parse_long(const char *str, long *val, long min, long max) 539 { 540 long rval; 541 char *end; 542 543 if (!str) 544 return 0; 545 546 errno = 0; 547 rval = strtol(str, &end, 10); 548 549 if (str == end || *end != '\0') 550 return EINVAL; 551 552 if (errno) 553 return errno; 554 555 if (rval > max || rval < min) 556 return ERANGE; 557 558 *val = rval; 559 return 0; 560 } 561 562 int tst_parse_float(const char *str, float *val, float min, float max) 563 { 564 double rval; 565 char *end; 566 567 if (!str) 568 return 0; 569 570 errno = 0; 571 rval = strtod(str, &end); 572 573 if (str == end || *end != '\0') 574 return EINVAL; 575 576 if (errno) 577 return errno; 578 579 if (rval > (double)max || rval < (double)min) 580 return ERANGE; 581 582 *val = (float)rval; 583 return 0; 584 } 585 586 static void do_exit(int ret) 587 { 588 if (results) { 589 printf("\nSummary:\n"); 590 printf("passed %d\n", results->passed); 591 printf("failed %d\n", results->failed); 592 printf("skipped %d\n", results->skipped); 593 printf("warnings %d\n", results->warnings); 594 595 if (results->passed && ret == TCONF) 596 ret = 0; 597 598 if (results->failed) 599 ret |= TFAIL; 600 601 if (results->skipped && !results->passed) 602 ret |= TCONF; 603 604 if (results->warnings) 605 ret |= TWARN; 606 } 607 608 do_cleanup(); 609 610 exit(ret); 611 } 612 613 void check_kver(void) 614 { 615 int v1, v2, v3; 616 617 if (tst_parse_kver(tst_test->min_kver, &v1, &v2, &v3)) { 618 tst_res(TWARN, 619 "Invalid kernel version %s, expected %%d.%%d.%%d", 620 tst_test->min_kver); 621 } 622 623 if (tst_kvercmp(v1, v2, v3) < 0) { 624 tst_brk(TCONF, "The test requires kernel %s or newer", 625 tst_test->min_kver); 626 } 627 } 628 629 static int results_equal(struct results *a, struct results *b) 630 { 631 if (a->passed != b->passed) 632 return 0; 633 634 if (a->failed != b->failed) 635 return 0; 636 637 if (a->skipped != b->skipped) 638 return 0; 639 640 return 1; 641 } 642 643 static int needs_tmpdir(void) 644 { 645 return tst_test->needs_tmpdir || 646 tst_test->needs_device || 647 tst_test->mntpoint || 648 tst_test->resource_files || 649 tst_test->needs_checkpoints; 650 } 651 652 static void copy_resources(void) 653 { 654 unsigned int i; 655 656 for (i = 0; tst_test->resource_files[i]; i++) 657 TST_RESOURCE_COPY(NULL, tst_test->resource_files[i], NULL); 658 } 659 660 static const char *get_tid(char *argv[]) 661 { 662 char *p; 663 664 if (!argv[0] || !argv[0][0]) { 665 tst_res(TINFO, "argv[0] is empty!"); 666 return "ltp_empty_argv"; 667 } 668 669 p = strrchr(argv[0], '/'); 670 if (p) 671 return p+1; 672 673 return argv[0]; 674 } 675 676 static struct tst_device tdev; 677 struct tst_device *tst_device; 678 679 static void assert_test_fn(void) 680 { 681 int cnt = 0; 682 683 if (tst_test->test) 684 cnt++; 685 686 if (tst_test->test_all) 687 cnt++; 688 689 if (tst_test->sample) 690 cnt++; 691 692 if (!cnt) 693 tst_brk(TBROK, "No test function speficied"); 694 695 if (cnt != 1) 696 tst_brk(TBROK, "You can define only one test function"); 697 698 if (tst_test->test && !tst_test->tcnt) 699 tst_brk(TBROK, "Number of tests (tcnt) must not be > 0"); 700 701 if (!tst_test->test && tst_test->tcnt) 702 tst_brk(TBROK, "You can define tcnt only for test()"); 703 } 704 705 static int prepare_and_mount_ro_fs(const char *dev, 706 const char *mntpoint, 707 const char *fs_type) 708 { 709 char buf[PATH_MAX]; 710 711 if (mount(dev, mntpoint, fs_type, 0, NULL)) { 712 tst_res(TINFO | TERRNO, "Can't mount %s at %s (%s)", 713 dev, mntpoint, fs_type); 714 return 1; 715 } 716 717 mntpoint_mounted = 1; 718 719 snprintf(buf, sizeof(buf), "%s/dir/", mntpoint); 720 SAFE_MKDIR(buf, 0777); 721 722 snprintf(buf, sizeof(buf), "%s/file", mntpoint); 723 SAFE_FILE_PRINTF(buf, "file content"); 724 SAFE_CHMOD(buf, 0777); 725 726 SAFE_MOUNT(dev, mntpoint, fs_type, MS_REMOUNT | MS_RDONLY, NULL); 727 728 return 0; 729 } 730 731 static void prepare_and_mount_dev_fs(const char *mntpoint) 732 { 733 const char *flags[] = {"nodev", NULL}; 734 int mounted_nodev; 735 736 mounted_nodev = tst_path_has_mnt_flags(NULL, flags); 737 if (mounted_nodev) { 738 tst_res(TINFO, "tmpdir isn't suitable for creating devices, " 739 "mounting tmpfs without nodev on %s", mntpoint); 740 SAFE_MOUNT(NULL, mntpoint, "tmpfs", 0, NULL); 741 mntpoint_mounted = 1; 742 } 743 } 744 745 static void prepare_device(void) 746 { 747 if (tst_test->format_device) { 748 SAFE_MKFS(tdev.dev, tdev.fs_type, tst_test->dev_fs_opts, 749 tst_test->dev_extra_opts); 750 } 751 752 if (tst_test->needs_rofs) { 753 prepare_and_mount_ro_fs(tdev.dev, tst_test->mntpoint, 754 tdev.fs_type); 755 return; 756 } 757 758 if (tst_test->mount_device) { 759 SAFE_MOUNT(tdev.dev, tst_test->mntpoint, tdev.fs_type, 760 tst_test->mnt_flags, tst_test->mnt_data); 761 mntpoint_mounted = 1; 762 } 763 } 764 765 static void do_setup(int argc, char *argv[]) 766 { 767 if (!tst_test) 768 tst_brk(TBROK, "No tests to run"); 769 770 if (tst_test->tconf_msg) 771 tst_brk(TCONF, "%s", tst_test->tconf_msg); 772 773 assert_test_fn(); 774 775 tid = get_tid(argv); 776 777 if (tst_test->sample) 778 tst_test = tst_timer_test_setup(tst_test); 779 780 parse_opts(argc, argv); 781 782 if (tst_test->needs_root && geteuid() != 0) 783 tst_brk(TCONF, "Test needs to be run as root"); 784 785 if (tst_test->min_kver) 786 check_kver(); 787 788 if (tst_test->needs_drivers) { 789 const char *name; 790 int i; 791 792 for (i = 0; (name = tst_test->needs_drivers[i]); ++i) 793 if (tst_check_driver(name)) 794 tst_brk(TCONF, "%s driver not available", name); 795 } 796 797 if (tst_test->format_device) 798 tst_test->needs_device = 1; 799 800 if (tst_test->mount_device) { 801 tst_test->needs_device = 1; 802 tst_test->format_device = 1; 803 } 804 805 if (tst_test->all_filesystems) 806 tst_test->needs_device = 1; 807 808 setup_ipc(); 809 810 if (needs_tmpdir() && !tst_tmpdir_created()) 811 tst_tmpdir(); 812 813 if (tst_test->save_restore) { 814 const char * const *name = tst_test->save_restore; 815 816 while (*name) { 817 tst_sys_conf_save(*name); 818 name++; 819 } 820 } 821 822 if (tst_test->mntpoint) 823 SAFE_MKDIR(tst_test->mntpoint, 0777); 824 825 if ((tst_test->needs_devfs || tst_test->needs_rofs || 826 tst_test->mount_device || tst_test->all_filesystems) && 827 !tst_test->mntpoint) { 828 tst_brk(TBROK, "tst_test->mntpoint must be set!"); 829 } 830 831 if (!!tst_test->needs_rofs + !!tst_test->needs_devfs + 832 !!tst_test->needs_device > 1) { 833 tst_brk(TBROK, 834 "Two or more of needs_{rofs, devfs, device} are set"); 835 } 836 837 if (tst_test->needs_devfs) 838 prepare_and_mount_dev_fs(tst_test->mntpoint); 839 840 if (tst_test->needs_rofs) { 841 /* If we failed to mount read-only tmpfs. Fallback to 842 * using a device with read-only filesystem. 843 */ 844 if (prepare_and_mount_ro_fs(NULL, tst_test->mntpoint, "tmpfs")) { 845 tst_res(TINFO, "Can't mount tmpfs read-only, " 846 "falling back to block device..."); 847 tst_test->needs_device = 1; 848 tst_test->format_device = 1; 849 } 850 } 851 852 if (tst_test->needs_device && !mntpoint_mounted) { 853 tdev.dev = tst_acquire_device_(NULL, tst_test->dev_min_size); 854 855 if (!tdev.dev) 856 tst_brk(TCONF, "Failed to acquire device"); 857 858 tst_device = &tdev; 859 860 if (tst_test->dev_fs_type) 861 tdev.fs_type = tst_test->dev_fs_type; 862 else 863 tdev.fs_type = tst_dev_fs_type(); 864 865 if (!tst_test->all_filesystems) 866 prepare_device(); 867 } 868 869 if (tst_test->resource_files) 870 copy_resources(); 871 } 872 873 static void do_test_setup(void) 874 { 875 main_pid = getpid(); 876 877 if (tst_test->setup) 878 tst_test->setup(); 879 880 if (main_pid != getpid()) 881 tst_brk(TBROK, "Runaway child in setup()!"); 882 } 883 884 static void do_cleanup(void) 885 { 886 if (mntpoint_mounted) 887 tst_umount(tst_test->mntpoint); 888 889 if (tst_test->needs_device && tdev.dev) 890 tst_release_device(tdev.dev); 891 892 if (tst_tmpdir_created()) { 893 /* avoid munmap() on wrong pointer in tst_rmdir() */ 894 tst_futexes = NULL; 895 tst_rmdir(); 896 } 897 898 if (tst_test->save_restore) 899 tst_sys_conf_restore(0); 900 901 cleanup_ipc(); 902 } 903 904 static void run_tests(void) 905 { 906 unsigned int i; 907 struct results saved_results; 908 909 if (!tst_test->test) { 910 saved_results = *results; 911 tst_test->test_all(); 912 913 if (getpid() != main_pid) { 914 exit(0); 915 } 916 917 tst_reap_children(); 918 919 if (results_equal(&saved_results, results)) 920 tst_brk(TBROK, "Test haven't reported results!"); 921 return; 922 } 923 924 for (i = 0; i < tst_test->tcnt; i++) { 925 saved_results = *results; 926 tst_test->test(i); 927 928 if (getpid() != main_pid) { 929 exit(0); 930 } 931 932 tst_reap_children(); 933 934 if (results_equal(&saved_results, results)) 935 tst_brk(TBROK, "Test %i haven't reported results!", i); 936 } 937 } 938 939 static unsigned long long get_time_ms(void) 940 { 941 struct timespec ts; 942 943 if (tst_clock_gettime(CLOCK_MONOTONIC, &ts)) 944 tst_brk(TBROK | TERRNO, "tst_clock_gettime()"); 945 946 return tst_timespec_to_ms(ts); 947 } 948 949 static void add_paths(void) 950 { 951 char *old_path = getenv("PATH"); 952 const char *start_dir; 953 char *new_path; 954 955 start_dir = tst_get_startwd(); 956 957 if (old_path) 958 SAFE_ASPRINTF(&new_path, "%s::%s", old_path, start_dir); 959 else 960 SAFE_ASPRINTF(&new_path, "::%s", start_dir); 961 962 SAFE_SETENV("PATH", new_path, 1); 963 free(new_path); 964 } 965 966 static void heartbeat(void) 967 { 968 if (tst_clock_gettime(CLOCK_MONOTONIC, &tst_start_time)) 969 tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); 970 971 kill(getppid(), SIGUSR1); 972 } 973 974 static void testrun(void) 975 { 976 unsigned int i = 0; 977 unsigned long long stop_time = 0; 978 int cont = 1; 979 980 heartbeat(); 981 add_paths(); 982 do_test_setup(); 983 984 if (duration > 0) 985 stop_time = get_time_ms() + (unsigned long long)(duration * 1000); 986 987 for (;;) { 988 cont = 0; 989 990 if (i < (unsigned int)iterations) { 991 i++; 992 cont = 1; 993 } 994 995 if (stop_time && get_time_ms() < stop_time) 996 cont = 1; 997 998 if (!cont) 999 break; 1000 1001 run_tests(); 1002 heartbeat(); 1003 } 1004 1005 do_test_cleanup(); 1006 exit(0); 1007 } 1008 1009 static pid_t test_pid; 1010 1011 1012 static volatile sig_atomic_t sigkill_retries; 1013 1014 #define WRITE_MSG(msg) do { \ 1015 if (write(2, msg, sizeof(msg) - 1)) { \ 1016 /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 */ \ 1017 } \ 1018 } while (0) 1019 1020 static void alarm_handler(int sig LTP_ATTRIBUTE_UNUSED) 1021 { 1022 WRITE_MSG("Test timeouted, sending SIGKILL!\n"); 1023 kill(-test_pid, SIGKILL); 1024 alarm(5); 1025 1026 if (++sigkill_retries > 10) { 1027 WRITE_MSG("Cannot kill test processes!\n"); 1028 WRITE_MSG("Congratulation, likely test hit a kernel bug.\n"); 1029 WRITE_MSG("Exitting uncleanly...\n"); 1030 _exit(TFAIL); 1031 } 1032 } 1033 1034 static void heartbeat_handler(int sig LTP_ATTRIBUTE_UNUSED) 1035 { 1036 alarm(results->timeout); 1037 sigkill_retries = 0; 1038 } 1039 1040 static void sigint_handler(int sig LTP_ATTRIBUTE_UNUSED) 1041 { 1042 if (test_pid > 0) { 1043 WRITE_MSG("Sending SIGKILL to test process...\n"); 1044 kill(-test_pid, SIGKILL); 1045 } 1046 } 1047 1048 unsigned int tst_timeout_remaining(void) 1049 { 1050 static struct timespec now; 1051 unsigned int elapsed; 1052 1053 if (tst_clock_gettime(CLOCK_MONOTONIC, &now)) 1054 tst_res(TWARN | TERRNO, "tst_clock_gettime() failed"); 1055 1056 elapsed = (tst_timespec_diff_ms(now, tst_start_time) + 500) / 1000; 1057 if (results->timeout > elapsed) 1058 return results->timeout - elapsed; 1059 1060 return 0; 1061 } 1062 1063 void tst_set_timeout(int timeout) 1064 { 1065 char *mul = getenv("LTP_TIMEOUT_MUL"); 1066 1067 if (timeout == -1) { 1068 tst_res(TINFO, "Timeout per run is disabled"); 1069 return; 1070 } 1071 1072 results->timeout = timeout; 1073 1074 if (mul) { 1075 float m = atof(mul); 1076 1077 if (m < 1) 1078 tst_brk(TBROK, "Invalid timeout multiplier '%s'", mul); 1079 1080 results->timeout = results->timeout * m + 0.5; 1081 } 1082 1083 tst_res(TINFO, "Timeout per run is %uh %02um %02us", 1084 results->timeout/3600, (results->timeout%3600)/60, 1085 results->timeout % 60); 1086 1087 if (getpid() == lib_pid) 1088 alarm(results->timeout); 1089 else 1090 heartbeat(); 1091 } 1092 1093 static int fork_testrun(void) 1094 { 1095 int status; 1096 1097 if (tst_test->timeout) 1098 tst_set_timeout(tst_test->timeout); 1099 else 1100 tst_set_timeout(300); 1101 1102 SAFE_SIGNAL(SIGINT, sigint_handler); 1103 1104 test_pid = fork(); 1105 if (test_pid < 0) 1106 tst_brk(TBROK | TERRNO, "fork()"); 1107 1108 if (!test_pid) { 1109 SAFE_SIGNAL(SIGALRM, SIG_DFL); 1110 SAFE_SIGNAL(SIGUSR1, SIG_DFL); 1111 SAFE_SIGNAL(SIGINT, SIG_DFL); 1112 SAFE_SETPGID(0, 0); 1113 testrun(); 1114 } 1115 1116 SAFE_WAITPID(test_pid, &status, 0); 1117 alarm(0); 1118 SAFE_SIGNAL(SIGINT, SIG_DFL); 1119 1120 if (WIFEXITED(status) && WEXITSTATUS(status)) 1121 return WEXITSTATUS(status); 1122 1123 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) { 1124 tst_res(TINFO, "If you are running on slow machine, " 1125 "try exporting LTP_TIMEOUT_MUL > 1"); 1126 tst_brk(TBROK, "Test killed! (timeout?)"); 1127 } 1128 1129 if (WIFSIGNALED(status)) 1130 tst_brk(TBROK, "Test killed by %s!", tst_strsig(WTERMSIG(status))); 1131 1132 return 0; 1133 } 1134 1135 static int run_tcases_per_fs(void) 1136 { 1137 int ret = 0; 1138 unsigned int i; 1139 const char *const *filesystems = tst_get_supported_fs_types(); 1140 1141 if (!filesystems[0]) 1142 tst_brk(TCONF, "There are no supported filesystems"); 1143 1144 for (i = 0; filesystems[i]; i++) { 1145 1146 tst_res(TINFO, "Testing on %s", filesystems[i]); 1147 tdev.fs_type = filesystems[i]; 1148 1149 prepare_device(); 1150 1151 ret = fork_testrun(); 1152 1153 if (mntpoint_mounted) { 1154 tst_umount(tst_test->mntpoint); 1155 mntpoint_mounted = 0; 1156 } 1157 1158 if (ret == TCONF) { 1159 update_results(ret); 1160 continue; 1161 } 1162 1163 if (ret == 0) 1164 continue; 1165 1166 do_exit(ret); 1167 } 1168 1169 return ret; 1170 } 1171 1172 void tst_run_tcases(int argc, char *argv[], struct tst_test *self) 1173 { 1174 int ret; 1175 1176 lib_pid = getpid(); 1177 tst_test = self; 1178 1179 do_setup(argc, argv); 1180 1181 TCID = tid; 1182 1183 SAFE_SIGNAL(SIGALRM, alarm_handler); 1184 SAFE_SIGNAL(SIGUSR1, heartbeat_handler); 1185 1186 if (tst_test->all_filesystems) 1187 ret = run_tcases_per_fs(); 1188 else 1189 ret = fork_testrun(); 1190 1191 do_exit(ret); 1192 } 1193 1194 1195 void tst_flush(void) 1196 { 1197 int rval; 1198 1199 rval = fflush(stderr); 1200 if (rval != 0) 1201 tst_brk(TBROK | TERRNO, "fflush(stderr) failed"); 1202 1203 rval = fflush(stderr); 1204 if (rval != 0) 1205 tst_brk(TBROK | TERRNO, "fflush(stdout) failed"); 1206 1207 } 1208