static void check_swapping(void) { int status, i; long swap_free_now, swapped; /* wait child stop */ SAFE_WAITPID(pid, &status, WUNTRACED); if (!WIFSTOPPED(status)) tst_brk(TBROK, "child was not stopped."); /* Still occupying memory, loop for a while */ i = 0; while (i < 10) { swap_free_now = SAFE_READ_MEMINFO("SwapFree:"); sleep(1); if (abs(swap_free_now - SAFE_READ_MEMINFO("SwapFree:")) < 512) break; i++; } swap_free_now = SAFE_READ_MEMINFO("SwapFree:"); swapped = swap_free_init - swap_free_now; if (swapped > mem_over_max) { kill(pid, SIGCONT); tst_brk(TFAIL, "heavy swapping detected: " "%ld MB swapped.", swapped / 1024); } tst_res(TPASS, "no heavy swapping detected, %ld MB swapped.", swapped / 1024); kill(pid, SIGCONT); /* wait child exit */ SAFE_WAITPID(pid, &status, 0); }
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; }
int main(int argc, char **argv) { int lc, status; tst_parse_opts(argc, argv, options, &help); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; SAFE_PIPE(cleanup, pipe_fd); /* the start of child_init_and_verify and child_write is * already synchronized via pipe */ pids[0] = fork(); switch (pids[0]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #0"); case 0: child_init_and_verify(); exit(0); default: break; } pids[1] = fork(); switch (pids[1]) { case -1: tst_brkm(TBROK | TERRNO, cleanup, "fork #1"); case 0: child_write(); exit(0); } /* wait until child_write writes into * child_init_and_verify's VM */ SAFE_WAITPID(cleanup, pids[1], &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 1 returns %d", status); /* signal child_init_and_verify to verify its VM now */ TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); SAFE_WAITPID(cleanup, pids[0], &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child 0 returns %d", status); } cleanup(); tst_exit(); }
void tst_record_childstatus(void (*cleanup)(void), pid_t child) { int status, ttype_result; NO_NEWLIB_ASSERT("Unknown", 0); SAFE_WAITPID(cleanup, child, &status, 0); if (WIFEXITED(status)) { ttype_result = WEXITSTATUS(status); ttype_result = TTYPE_RESULT(ttype_result); T_exitval |= ttype_result; if (ttype_result == TPASS) tst_resm(TINFO, "Child process returned TPASS"); if (ttype_result & TFAIL) tst_resm(TINFO, "Child process returned TFAIL"); if (ttype_result & TBROK) tst_resm(TINFO, "Child process returned TBROK"); if (ttype_result & TCONF) tst_resm(TINFO, "Child process returned TCONF"); } else { tst_brkm(TBROK, cleanup, "child process(%d) killed by " "unexpected signal %s(%d)", child, tst_strsig(WTERMSIG(status)), WTERMSIG(status)); } }
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 pid; void do_child(void); tst_parse_opts(ac, av, NULL, NULL); setup(); /* global setup */ if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "could not fork"); } if (pid == 0) { /* child */ /* set the user ID of the child to the non root user */ if (setuid(ltp_uid) == -1) { tst_resm(TBROK, "setuid() failed"); exit(1); } do_child(); } else { /* wait for the child to return */ SAFE_WAITPID(cleanup, pid, NULL, 0); /* if it exists, remove the shared memory resource */ rm_shm(shm_id_1); tst_rmdir(); } cleanup(); tst_exit(); }
static void verify_creat(void) { pid_t pid; pid = SAFE_FORK(); if (pid == 0) { char *av[] = {TEST_APP, NULL}; (void)execve(TEST_APP, av, tst_ipc_envp); perror("execve failed"); exit(1); } TST_CHECKPOINT_WAIT(0); TEST(creat(TEST_APP, O_WRONLY)); if (TEST_RETURN != -1) { tst_res(TFAIL, "creat() succeeded unexpectedly"); return; } if (TEST_ERRNO == ETXTBSY) tst_res(TPASS, "creat() received EXTBSY"); else tst_res(TFAIL | TTERRNO, "creat() failed unexpectedly"); SAFE_KILL(pid, SIGKILL); SAFE_WAITPID(pid, NULL, 0); }
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 stop_ksm_children(int *child, int num) { int k, status; tst_res(TINFO, "wait for all children to stop."); for (k = 0; k < num; k++) { SAFE_WAITPID(child[k], &status, WUNTRACED); if (!WIFSTOPPED(status)) tst_brk(TBROK, "child %d was not stopped", k); } }
int main(int ac, char **av) { int forks, pid1, fork_errno, waitstatus; int ret, status; int lc; tst_parse_opts(ac, av, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; tst_resm(TINFO, "Forking as many kids as possible"); forks = 0; while ((pid1 = fork()) != -1) { if (pid1 == 0) { /* child */ pause(); exit(0); } forks++; ret = SAFE_WAITPID(cleanup, -1, &status, WNOHANG); if (ret > 0) { /* a child may be killed by OOM killer */ if (WTERMSIG(status) == SIGKILL) break; tst_brkm(TBROK, cleanup, "child exit with error code %d or signal %d", WEXITSTATUS(status), WTERMSIG(status)); } } fork_errno = errno; /* parent */ tst_resm(TINFO, "Number of processes forked is %d", forks); tst_resm(TPASS, "fork() eventually failed with %d: %s", fork_errno, strerror(fork_errno)); /* collect our kids */ /* * Introducing a sleep(3) to make sure all children are * at pause() when SIGQUIT is sent to them */ sleep(3); kill(0, SIGQUIT); while (wait(&waitstatus) > 0) ; } cleanup(); tst_exit(); }
static void verify_access(unsigned int n) { struct tcase *tc = tcases + n; pid_t pid; access_test(tc, "root"); pid = SAFE_FORK(); if (pid) { SAFE_WAITPID(pid, NULL, 0); } else { SAFE_SETUID(uid); access_test(tc, "nobody"); } }
static void test_hugeshmctl(void) { pid_t pid; int status; switch (pid = SAFE_FORK()) { case 0: /* set the user ID of the child to the non root user */ SAFE_SETUID(ltp_uid); do_child(); exit(0); default: SAFE_WAITPID(pid, &status, 0); } }
static void verify_shmat(unsigned int n) { int *addr; pid_t pid; int status; struct shmid_ds buf; struct test_case_t *tc = &tcases[n]; addr = shmat(shm_id, *tc->shmaddr, tc->flag); if (addr == (void *)-1) { tst_res(TFAIL | TERRNO, "shmat() failed"); return; } SAFE_SHMCTL(shm_id, IPC_STAT, &buf); if (buf.shm_nattch != 1) { tst_res(TFAIL, "number of attaches was incorrect"); goto end; } if (buf.shm_segsz != INT_SIZE) { tst_res(TFAIL, "segment size was incorrect"); goto end; } if (expected_addr(*tc->shmaddr, addr) != addr) { tst_res(TFAIL, "shared memory address %p is not correct, expected %p", addr, expected_addr(*tc->shmaddr, addr)); goto end; } pid = SAFE_FORK(); if (!pid) do_child(addr, tc->exp_status == SIGSEGV); else SAFE_WAITPID(pid, &status, 0); if (expected_status(status, tc->exp_status)) tst_res(TFAIL, "shmat() failed to attach %s", tc->desp); else tst_res(TPASS, "shmat() succeeded to attach %s", tc->desp); end: SAFE_SHMDT(addr); }
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 int fork_testrun(void) { int status; if (tst_test->timeout) tst_set_timeout(tst_test->timeout); else tst_set_timeout(300); SAFE_SIGNAL(SIGINT, sigint_handler); test_pid = fork(); if (test_pid < 0) tst_brk(TBROK | TERRNO, "fork()"); if (!test_pid) { SAFE_SIGNAL(SIGALRM, SIG_DFL); SAFE_SIGNAL(SIGUSR1, SIG_DFL); SAFE_SIGNAL(SIGINT, SIG_DFL); SAFE_SETPGID(0, 0); testrun(); } SAFE_WAITPID(test_pid, &status, 0); alarm(0); SAFE_SIGNAL(SIGINT, SIG_DFL); if (WIFEXITED(status) && WEXITSTATUS(status)) return WEXITSTATUS(status); if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) { tst_res(TINFO, "If you are running on slow machine, " "try exporting LTP_TIMEOUT_MUL > 1"); tst_brk(TBROK, "Test killed! (timeout?)"); } if (WIFSIGNALED(status)) tst_brk(TBROK, "Test killed by %s!", tst_strsig(WTERMSIG(status))); return 0; }
/* * oom - allocates memory according to specified testcase and checks * desired outcome (e.g. child killed, operation failed with ENOMEM) * @testcase: selects how child allocates memory * valid choices are: NORMAL, MLOCK and KSM * @lite: if non-zero, child makes only single TESTMEM+MB allocation * if zero, child keeps allocating memory until it gets killed * or some operation fails * @retcode: expected return code of child process * if matches child ret code, this function reports PASS, * otherwise it reports FAIL * @allow_sigkill: if zero and child is killed, this function reports FAIL * if non-zero, then if child is killed by SIGKILL * it is considered as PASS */ void oom(int testcase, int lite, int retcode, int allow_sigkill) { pid_t pid; int status, threads; switch (pid = SAFE_FORK()) { case 0: threads = MAX(1, tst_ncpus() - 1); child_alloc(testcase, lite, threads); default: break; } tst_res(TINFO, "expected victim is %d.", pid); SAFE_WAITPID(-1, &status, 0); if (WIFSIGNALED(status)) { if (allow_sigkill && WTERMSIG(status) == SIGKILL) { tst_res(TPASS, "victim signalled: (%d) %s", SIGKILL, tst_strsig(SIGKILL)); } else { tst_res(TFAIL, "victim signalled: (%d) %s", WTERMSIG(status), tst_strsig(WTERMSIG(status))); } } else if (WIFEXITED(status)) { if (WEXITSTATUS(status) == retcode) { tst_res(TPASS, "victim retcode: (%d) %s", retcode, strerror(retcode)); } else { tst_res(TFAIL, "victim unexpectedly ended with " "retcode: %d, expected: %d", WEXITSTATUS(status), retcode); } } else { tst_res(TFAIL, "victim unexpectedly ended"); } }
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(); }