1853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy/* 2853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * Copyright (c) 2013 Fujitsu Ltd. 3853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com> 4853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * 5853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * This program is free software; you can redistribute it and/or modify it 6853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * under the terms of version 2 of the GNU General Public License as 7853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * published by the Free Software Foundation. 8853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * 9853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * This program is distributed in the hope that it would be useful, but 10853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * WITHOUT ANY WARRANTY; without even the implied warranty of 11853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * 13853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * You should have received a copy of the GNU General Public License along 14853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * with this program. 15853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy */ 16853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 1750a1afe70594d7b8cbf0086e77fb1be9e154beb5Cyril Hrubis#define _GNU_SOURCE 18853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include <errno.h> 19853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include <sched.h> 20853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include <sys/wait.h> 21853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include "test.h" 22853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include "clone_platform.h" 23853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include "safe_macros.h" 24853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#include "linux_syscall_numbers.h" 25853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 261db62666ceab32282807215bb2882a3cfa5979fdZeng Linggangchar *TCID = "clone08"; 271db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang 28853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic pid_t ptid, ctid, tgid; 29853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void *child_stack; 30853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 31853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void setup(void); 32853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void cleanup(void); 33853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 34853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_parent(int t); 35853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_parent(void); 36853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic pid_t parent_ppid; 37853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 38853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_tid(int t); 39853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_child_settid(void); 40853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_parent_settid(void); 41853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 42853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#ifdef CLONE_STOPPED 43853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_stopped(int t); 44853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_stopped(void); 45853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int stopped_flag; 46853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#endif 47853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 48853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_thread(int t); 49853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_thread(void); 50853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int tst_result; 51853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 52853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy/* 53853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * Children cloned with CLONE_VM should avoid using any functions that 54853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * might require dl_runtime_resolve, because they share thread-local 55853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * storage with parent. If both try to resolve symbols at same time you 56853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * can crash, likely at _dl_x86_64_restore_sse(). 57853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * See this thread for relevant discussion: 58853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy * http://www.mail-archive.com/utrace-devel@redhat.com/msg01944.html 59853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy */ 60853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic struct test_case { 61853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy char *name; 62853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int flags; 63853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy void (*testfunc)(int); 64853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int (*do_child)(); 65853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} test_cases[] = { 66853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy {"CLONE_PARENT", CLONE_PARENT | SIGCHLD, 67853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_clone_parent, child_clone_parent}, 68853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | SIGCHLD, 69853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_clone_tid, child_clone_child_settid}, 70853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | SIGCHLD, 71853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_clone_tid, child_clone_parent_settid}, 72853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#ifdef CLONE_STOPPED 73853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy {"CLONE_STOPPED", CLONE_STOPPED | CLONE_VM | SIGCHLD, 74853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_clone_stopped, child_clone_stopped}, 75853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#endif 76853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy {"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | SIGCHLD, 77853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_clone_thread, child_clone_thread}, 78853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy}; 79853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 80853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jyint TST_TOTAL = ARRAY_SIZE(test_cases); 81853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 82853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jyint main(int ac, char **av) 83853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 84853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int i, lc; 85853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 86d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis tst_parse_opts(ac, av, NULL, NULL); 87853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 88853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy setup(); 89853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy for (lc = 0; TEST_LOOPING(lc); lc++) { 90853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_count = 0; 91853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy for (i = 0; i < TST_TOTAL; i++) { 92853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TINFO, "running %s", test_cases[i].name); 93853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[i].testfunc(i); 94853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 95853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 96853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy cleanup(); 97853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_exit(); 98853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 99853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 100853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void setup(void) 101853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 102853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_sig(FORK, DEF_HANDLER, cleanup); 103853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 104853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy TEST_PAUSE; 105853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 106853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_tmpdir(); 107853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 108853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child_stack = SAFE_MALLOC(cleanup, CHILD_STACK_SIZE); 109853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 110853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 111853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void cleanup(void) 112853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 113853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy free(child_stack); 114853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 115853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_rmdir(); 116853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 117853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 118853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic long clone_child(const struct test_case *t, int use_tst) 119853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 1201db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang TEST(ltp_clone7(t->flags, t->do_child, NULL, CHILD_STACK_SIZE, 121853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child_stack, &ptid, NULL, &ctid)); 1221db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang 1231db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang if (TEST_RETURN == -1 && TTERRNO == ENOSYS) 1241db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang tst_brkm(TCONF, cleanup, "clone does not support 7 args"); 1251db62666ceab32282807215bb2882a3cfa5979fdZeng Linggang 126853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (TEST_RETURN == -1) { 127853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (use_tst) { 128853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_brkm(TBROK | TTERRNO, cleanup, "%s clone() failed", 129853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy t->name); 130853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 131853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy printf("%s clone() failed, errno: %d", 132853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy t->name, TEST_ERRNO); 133853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy exit(1); 134853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 135853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 136853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return TEST_RETURN; 137853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 138853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 139853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int wait4child(pid_t child) 140853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 141853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int status; 142853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 143853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (waitpid(child, &status, 0) == -1) 144853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TBROK|TERRNO, "waitpid"); 145853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (WIFEXITED(status)) 146853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return WEXITSTATUS(status); 147853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy else 148853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return status; 149853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 150853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 151853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_parent(int t) 152853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 153853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int status; 154853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy pid_t child; 155853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 156853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy fflush(stdout); 157853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child = FORK_OR_VFORK(); 158853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy switch (child) { 159853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy case 0: 160853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy parent_ppid = getppid(); 161853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy clone_child(&test_cases[t], 0); 162853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy exit(0); 163853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy case -1: 164853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_brkm(TBROK | TERRNO, NULL, "test_clone_parent fork"); 165853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy default: 166853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy status = wait4child(child); 167853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (status == 0) { 168853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy /* wait for CLONE_PARENT child */ 169853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy status = wait4child(-1); 170853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (status == 0) { 171853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TPASS, "test %s", test_cases[t].name); 172853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 173853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TFAIL, "test %s, status: %d", 174853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[t].name, status); 175853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 176853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 177853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TFAIL, "test %s, status: %d", 178853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[t].name, status); 179853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 180853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy }; 181853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 182853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 183853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_parent(void) 184853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 185853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (parent_ppid == getppid()) 186853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy exit(0); 187853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy printf("FAIL: getppid != parent_ppid (%d != %d)\n", 188853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy parent_ppid, getppid()); 189853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy exit(1); 190853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 191853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 192853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_tid(int t) 193853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 194853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int status; 195853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy pid_t child; 196853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 197853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child = clone_child(&test_cases[t], 1); 198853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy status = wait4child(child); 199853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (status == 0) { 200853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TPASS, "test %s", test_cases[t].name); 201853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 202853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TFAIL, "test %s, status: %d", 203853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[t].name, status); 204853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 205853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 206853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 207853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_child_settid(void) 208853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 209853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (ctid == ltp_syscall(__NR_getpid)) 210853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 0); 211853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy printf("FAIL: ctid != getpid() (%d != %d)\n", 212853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ctid, getpid()); 213853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 1); 214853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return 0; 215853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 216853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 217853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_parent_settid(void) 218853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 219853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (ptid == ltp_syscall(__NR_getpid)) 220853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 0); 221853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy printf("FAIL: ptid != getpid() (%d != %d)\n", 222853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ptid, getpid()); 223853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 1); 224853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return 0; 225853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 226853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 227853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#ifdef CLONE_STOPPED 228853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_stopped(int t) 229853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 230853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int i; 231853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int status; 232853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int flag; 233853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy pid_t child; 234853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 235dc054fbc2a0efee8abfa395e0a5ea817896023f9Shuang Qiu if (tst_kvercmp(2, 6, 38) >= 0) { 236dc054fbc2a0efee8abfa395e0a5ea817896023f9Shuang Qiu tst_resm(TINFO, "CLONE_STOPPED skipped for kernels >= 2.6.38"); 237dc054fbc2a0efee8abfa395e0a5ea817896023f9Shuang Qiu return; 238dc054fbc2a0efee8abfa395e0a5ea817896023f9Shuang Qiu } 239dc054fbc2a0efee8abfa395e0a5ea817896023f9Shuang Qiu 240853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy stopped_flag = 0; 241853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child = clone_child(&test_cases[t], 1); 242853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 243853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy /* give the kernel scheduler chance to run the CLONE_STOPPED thread*/ 244853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy for (i = 0; i < 100; i++) { 245853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy sched_yield(); 246853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy usleep(1000); 247853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 248853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 249853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy flag = stopped_flag; 250853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (kill(child, SIGCONT) != 0) 251853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_brkm(TBROK | TERRNO, cleanup, "kill SIGCONT failed"); 252853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 253853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy status = wait4child(child); 254853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (status == 0 && flag == 0) { 255853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TPASS, "test %s", test_cases[t].name); 256853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 257853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TFAIL, "test %s, status: %d, flag: %d", 258853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[t].name, status, flag); 259853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 260853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 261853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 262853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_stopped(void) 263853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 264853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy stopped_flag = 1; 265853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 0); 266853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return 0; 267853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 268853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy#endif 269853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 270853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic void test_clone_thread(int t) 271853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 272853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy pid_t child; 273853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy int i, status; 274853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 275853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy fflush(stdout); 276853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy child = FORK_OR_VFORK(); 277853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy switch (child) { 278853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy case 0: 279853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tgid = ltp_syscall(__NR_getpid); 280853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_result = -1; 281853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy clone_child(&test_cases[t], 0); 282853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 283853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy for (i = 0; i < 5000; i++) { 284853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy sched_yield(); 285853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy usleep(1000); 286853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (tst_result != -1) 287853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy break; 288853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 289853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, tst_result); 290853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy case -1: 291853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_brkm(TBROK | TERRNO, NULL, "test_clone_thread fork"); 292853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy default: 293853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy status = wait4child(child); 294853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (status == 0) { 295853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TPASS, "test %s", test_cases[t].name); 296853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } else { 297853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_resm(TFAIL, "test %s, status: %d", 298853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy test_cases[t].name, status); 299853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy } 300853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy }; 301853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 302853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy 303853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jystatic int child_clone_thread(void) 304853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy{ 305853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy if (tgid == ltp_syscall(__NR_getpid)) 306853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_result = TPASS; 307853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy else 308853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy tst_result = TFAIL; 309853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy ltp_syscall(__NR_exit, 0); 310853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy return 0; 311853f9811db8ef4a948e70df9b81ed219de7e842ezenglg.jy} 312