int main(int ac, char **av) { int lc; int pid; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); ++lc) { pid = tst_fork(); switch (pid) { case 0: send_events(); exit(0); case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); default: if (!check_events()) tst_resm(TFAIL, "Wrong data received in eventX"); else tst_resm(TPASS, "Data received in eventX"); break; } SAFE_WAITPID(NULL, pid, NULL, 0); } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; int i; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (i = 0; i < TST_TOTAL; ++i) { pid2 = tst_fork(); if (pid2 == -1) tst_brkm(TBROK, cleanup, "fork failed"); if (!pid2) do_child(&test_cases[i]); else tst_record_childstatus(cleanup, pid2); tst_count++; } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; int pid; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); ++lc) { pid = tst_fork(); fd2 = open_device(); switch (pid) { case 0: send_information(); exit(0); case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); default: if (no_events_queued(fd2, 0)) tst_resm(TPASS, "No data received in eventX"); else tst_resm(TFAIL, "Data received in eventX"); SAFE_CLOSE(NULL, fd2); break; } SAFE_WAITPID(NULL, pid, NULL, 0); } cleanup(); tst_exit(); }
static void do_test(int i) { pid_t cpid; cpid = tst_fork(); if (cpid < 0) tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); if (cpid == 0) do_child(i); fd = SAFE_OPEN(cleanup, "file", O_RDONLY); TEST(fcntl(fd, F_SETLEASE, test_cases[i].lease_type)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "fcntl() failed to set lease"); SAFE_WAITPID(cleanup, cpid, NULL, 0); SAFE_CLOSE(cleanup, fd); fd = 0; return; } /* Wait for SIGIO caused by lease breaker. */ TEST(sigtimedwait(&newset, NULL, &timeout)); if (TEST_RETURN == -1) { if (TEST_ERRNO == EAGAIN) { tst_resm(TFAIL | TTERRNO, "failed to receive SIGIO " "within %lis", timeout.tv_sec); SAFE_WAITPID(cleanup, cpid, NULL, 0); SAFE_CLOSE(cleanup, fd); fd = 0; return; } tst_brkm(TBROK | TTERRNO, cleanup, "sigtimedwait() failed"); } /* Try to downgrade or remove the lease. */ switch (test_cases[i].lease_type) { case F_WRLCK: TEST(fcntl(fd, F_SETLEASE, F_RDLCK)); if (TEST_RETURN == 0) break; case F_RDLCK: TEST(fcntl(fd, F_SETLEASE, F_UNLCK)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "fcntl() failed to remove the lease"); } break; default: break; } tst_record_childstatus(cleanup, cpid); SAFE_CLOSE(cleanup, fd); fd = 0; }
void testfunc_cloexec(void) { pid_t pid; int status; char buf[20]; if ((tst_kvercmp(2, 6, 23)) < 0) { tst_resm(TCONF, "test O_CLOEXEC flags for openat " "needs kernel 2.6.23 or higher"); return; } TEST(openat(AT_FDCWD, TEST_FILE, O_CLOEXEC | O_RDWR, 0777)); if (TEST_RETURN == -1) { tst_resm(TFAIL | TTERRNO, "openat failed"); return; } sprintf(buf, "%ld", TEST_RETURN); pid = tst_fork(); if (pid < 0) tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); if (pid == 0) { if (execlp(TEST_APP, TEST_APP, buf, NULL)) exit(2); } SAFE_CLOSE(cleanup, TEST_RETURN); if (wait(&status) == -1) tst_brkm(TBROK | TERRNO, cleanup, "wait() failed"); if (WIFEXITED(status)) { switch ((int8_t)WEXITSTATUS(status)) { case 0: tst_resm(TPASS, "test O_CLOEXEC for openat success"); break; case 1: tst_resm(TFAIL, "test O_CLOEXEC for openat failed"); break; default: tst_brkm(TBROK, cleanup, "execlp() failed"); } } else { tst_brkm(TBROK, cleanup, "openat2_exec exits with unexpected error"); } }
static void do_test(void) { int fd, ret, status; pid_t child; char buf[FS_BLOCKSIZE]; SAFE_TOUCH(cleanup, "testfilep", 0644, NULL); SAFE_TOUCH(cleanup, "testfilec", 0644, NULL); child = tst_fork(); switch (child) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); case 0: do_child(); default: fd = SAFE_OPEN(cleanup, "testfilep", O_RDWR); memset(buf, 'a', FS_BLOCKSIZE); TST_SAFE_CHECKPOINT_WAIT(cleanup, 0); while (1) { ret = write(fd, buf, FS_BLOCKSIZE); if (ret < 0) { if (errno == ENOSPC) { break; } else { tst_brkm(TBROK | TERRNO, cleanup, "write failed unexpectedly"); } } } SAFE_CLOSE(cleanup, fd); TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); } wait(&status); if (WIFEXITED(status) && WEXITSTATUS(status) == 1) { bug_reproduced = 1; } else { /* * If child process was killed by SIGBUS, bug is not reproduced. */ if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGBUS) { tst_brkm(TBROK | TERRNO, cleanup, "child process terminate unexpectedly"); } } SAFE_UNLINK(cleanup, "testfilep"); SAFE_UNLINK(cleanup, "testfilec"); }
/* * We do the real test in a child because with the test -i parameter the loop * that checks that all threads are sleeping may fail with ENOENT. That is * because some of the threads from previous run may still be there. * * Which is because the userspace part of pthread_join() sleeps in a futex on a * pthread tid which is woken up at the end of the exit_mm(tsk) which is before * the process is removed from the parent thread_group list. So there is a * small race window where the readdir() returns the process tid as a directory * under /proc/$PID/tasks/, but the subsequent open() fails with ENOENT because * the thread was removed meanwhile. */ static void verify_futex_wake(void) { int pid; pid = tst_fork(); switch (pid) { case 0: do_child(); case -1: tst_brkm(TBROK | TERRNO, NULL, "fork() failed"); default: tst_record_childstatus(NULL, pid); } }
static void setup(void) { tst_require_root(NULL); uid = geteuid(); ncpus = tst_ncpus_max(); /* Current mask */ mask = CPU_ALLOC(ncpus); if (mask == NULL) tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", ncpus); mask_size = CPU_ALLOC_SIZE(ncpus); if (sched_getaffinity(0, mask_size, mask) < 0) tst_brkm(TBROK | TERRNO, cleanup, "sched_getaffinity() failed"); /* Mask with one more cpu than available on the system */ emask = CPU_ALLOC(ncpus + 1); if (emask == NULL) tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", ncpus + 1); emask_size = CPU_ALLOC_SIZE(ncpus + 1); CPU_ZERO_S(emask_size, emask); CPU_SET_S(ncpus, emask_size, emask); privileged_pid = tst_fork(); if (privileged_pid == 0) { pause(); exit(0); } else if (privileged_pid < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); } /* Dropping the root privileges */ ltpuser = getpwnam(nobody_uid); if (ltpuser == NULL) tst_brkm(TBROK | TERRNO, cleanup, "getpwnam failed for user id %s", nobody_uid); SAFE_SETEUID(cleanup, ltpuser->pw_uid); /* this pid is not used by the OS */ free_pid = tst_get_unused_pid(cleanup); }
static void test(void) { pid_t pid; int status; /* unshares the network namespace */ if (unshare(CLONE_NEWNET) == -1) tst_brkm(TBROK | TERRNO, cleanup, "unshare failed"); pid = tst_fork(); if (pid < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); } if (pid == 0) { _exit(child_func()); } /* creates TAP network interface dummy0 */ if (WEXITSTATUS(system("ip tuntap add dev dummy0 mode tap")) == -1) tst_brkm(TBROK | TERRNO, cleanup, "system failed"); /* removes previously created dummy0 device */ if (WEXITSTATUS(system("ip tuntap del mode tap dummy0")) == -1) tst_brkm(TBROK | TERRNO, cleanup, "system failed"); /* allow child to continue */ TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); SAFE_WAITPID(cleanup, pid, &status, 0); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { tst_resm(TFAIL, "netlink interface fail"); return; } if (WIFSIGNALED(status)) { tst_resm(TFAIL, "child was killed with signal %s", tst_strsig(WTERMSIG(status))); return; } tst_resm(TPASS, "netlink interface pass"); }
static void *fork_thread(void *arg) { pid_t pid; (void) arg; while (!done) { pid = tst_fork(); if (pid == 0) { exit(0); } else if (pid < 0) { fprintf(stderr, "Failed to fork child: %s.\n", strerror(errno)); return (void *) 1; } waitpid(pid, NULL, 0); usleep(100); } return NULL; }
int main(int ac, char **av) { int status; char cur_cwd[PATH_MAX]; pid_t child; tst_parse_opts(ac, av, NULL, NULL); setup(); child = tst_fork(); if (child < 0) tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); if (child == 0) do_child(); while (1) { SAFE_GETCWD(cleanup, cur_cwd, PATH_MAX); if (strncmp(init_cwd, cur_cwd, PATH_MAX)) { tst_resm(TFAIL, "initial current work directory is " "%s, now is %s. Bug is reproduced!", init_cwd, cur_cwd); break; } if (end) { tst_resm(TPASS, "Bug is not reproduced!"); break; } } SAFE_KILL(cleanup, child, SIGKILL); SAFE_WAITPID(cleanup, child, &status, 0); cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; int pid; tst_parse_opts(ac, av, NULL, NULL); for (lc = 0; lc < TEST_LOOPING(lc); ++lc) { setup(); pid = tst_fork(); fd2 = setup_read(); if (!pid) { send_information(); } else { if (check_information()) tst_resm(TFAIL, "Data received in eventX"); else tst_resm(TPASS, "No data received in eventX"); } } tst_exit(); }
static void max_map_count_test(void) { int status; pid_t pid; long max_maps; long map_count; long max_iters; long memfree; /* * XXX Due to a possible kernel bug, oom-killer can be easily * triggered when doing small piece mmaps in huge amount even if * enough free memory available. Also it has been observed that * oom-killer often kill wrong victims in this situation, we * decided to do following steps to make sure no oom happen: * 1) use a safe maximum max_map_count value as upper-bound, * we set it 65536 in this case, i.e., we don't test too big * value; * 2) make sure total mapping isn't larger tha * CommitLimit - Committed_AS * and set overcommit_memory to 2, this could help mapping * returns ENOMEM instead of triggering oom-killer when * memory is tight. (When there are enough free memory, * step 1) will be used first. * Hope OOM-killer can be more stable oneday. */ memfree = read_meminfo("CommitLimit:") - read_meminfo("Committed_AS:"); /* 64 used as a bias to make sure no overflow happen */ max_iters = memfree / sysconf(_SC_PAGESIZE) * 1024 - 64; if (max_iters > MAX_MAP_COUNT) max_iters = MAX_MAP_COUNT; max_maps = MAP_COUNT_DEFAULT; while (max_maps <= max_iters) { set_sys_tune("max_map_count", max_maps, 1); switch (pid = tst_fork()) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork"); case 0: while (mmap(NULL, 1, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0) != MAP_FAILED) ; if (raise(SIGSTOP) != 0) tst_brkm(TBROK | TERRNO, tst_exit, "raise"); exit(0); default: break; } /* wait child done mmap and stop */ if (waitpid(pid, &status, WUNTRACED) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); if (!WIFSTOPPED(status)) tst_brkm(TBROK, cleanup, "child did not stopped"); map_count = count_maps(pid); /* Note max_maps will be exceeded by one for * the sysctl setting of max_map_count. This * is the mm failure point at the time of * writing this COMMENT! */ if (map_count == (max_maps + 1)) tst_resm(TPASS, "%ld map entries in total " "as expected.", max_maps); else tst_resm(TFAIL, "%ld map entries in total, but " "expected %ld entries", map_count, max_maps); /* make child continue to exit */ if (kill(pid, SIGCONT) != 0) tst_brkm(TBROK | TERRNO, cleanup, "kill"); if (waitpid(pid, &status, 0) == -1) tst_brkm(TBROK | TERRNO, cleanup, "waitpid"); max_maps = max_maps << 1; } }