pidns17.c revision c2c8d7f6d8d77f9755a919bf8fdd858ba4c9fbdb
1/* 2* Copyright (c) International Business Machines Corp., 2007 3* This program is free software; you can redistribute it and/or modify 4* it under the terms of the GNU General Public License as published by 5* the Free Software Foundation; either version 2 of the License, or 6* (at your option) any later version. 7* This program is distributed in the hope that it will be useful, 8* but WITHOUT ANY WARRANTY; without even the implied warranty of 9* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 10* the GNU General Public License for more details. 11* You should have received a copy of the GNU General Public License 12* along with this program; if not, write to the Free Software 13* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 14* 15*************************************************************************** 16* File: pidns17.c 17* * 18* * Description: 19* * The pidns17.c testcase verifies inside the container, if kill(-1, SIGUSR1) 20* * terminates all children running inside. 21* * 22* * Test Assertion & Strategy: 23* * Create a PID namespace container. 24* * Spawn many children inside it. 25* * Invoke kill(-1, SIGUSR1) inside container and check if it terminates 26* * all children. 27* * 28* * Usage: <for command-line> 29* * pidns17 30* * 31* * History: 32* * DATE NAME DESCRIPTION 33* * 13/11/08 Gowrishankar M Creation of this test. 34* * <gowrishankar.m@in.ibm.com> 35* 36******************************************************************************/ 37#define _GNU_SOURCE 1 38#include <sys/wait.h> 39#include <sys/types.h> 40#include <string.h> 41#include <stdlib.h> 42#include <unistd.h> 43#include <stdio.h> 44#include <errno.h> 45#include <usctest.h> 46#include <test.h> 47#define CLEANUP cleanup 48#include "libclone.h" 49 50char *TCID = "pidns17"; 51int TST_TOTAL = 1; 52int errno; 53 54int child_fn(void *); 55 56#define CHILD_PID 1 57#define PARENT_PID 0 58 59/* 60 * child_fn() - Inside container 61 */ 62int child_fn(void *arg) 63{ 64 pid_t pid, ppid; 65 int i, children[10], status; 66 67 /* Set process id and parent pid */ 68 pid = getpid(); 69 ppid = getppid(); 70 if (pid != CHILD_PID || ppid != PARENT_PID) { 71 tst_brkm(TBROK | TERRNO, CLEANUP, "cinit: pidns is not created."); 72 } 73 74 /* Spawn many children */ 75 for (i = 0; i < (sizeof(children) / sizeof(children[0])); i++) { 76 switch ((children[i] = fork())) { 77 case -1: 78 tst_brkm(TBROK | TERRNO, CLEANUP, "fork failed"); 79 break; 80 case 0: 81 pause(); 82 exit(2); 83 break; 84 default: 85 /* fork succeeded. */ 86 break; 87 } 88 } 89 /* wait for last child to get scheduled */ 90 sleep(1); 91 92 if (kill(-1, SIGUSR1) == -1) { 93 tst_resm(TBROK | TERRNO, "cinit: kill(-1, SIGUSR1) failed"); 94 CLEANUP(); 95 } 96 97 for (i = 0; i < (sizeof(children) / sizeof(children[0])); i++) { 98 if (waitpid(children[i], &status, 0) == -1) { 99 tst_resm(TBROK | TERRNO, "cinit: waitpid() failed"); 100 CLEANUP(); 101 } 102 if (!(WIFSIGNALED(status) && WTERMSIG(status) == SIGUSR1)) { 103 tst_resm(TFAIL, "cinit: found a child alive still " 104 "%d exit: %d, %d, signal %d, %d", i, 105 WIFEXITED(status), WEXITSTATUS(status), 106 WIFSIGNALED(status), WTERMSIG(status)); 107 CLEANUP(); 108 } 109 } 110 tst_resm(TPASS, "cinit: all children are terminated."); 111 112 /* cleanup and exit */ 113 CLEANUP(); 114} 115 116/*********************************************************************** 117* M A I N 118***********************************************************************/ 119 120int main(int argc, char *argv[]) 121{ 122 int status, ret; 123 pid_t pid; 124 125 pid = getpid(); 126 127 /* Container creation on PID namespace */ 128 ret = do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn, NULL); 129 if (ret != 0) { 130 tst_resm(TBROK | TERRNO, "parent: clone() failed"); 131 CLEANUP(); 132 } 133 134 sleep(1); 135 if (waitpid(-1, &status, __WALL) < 0) 136 tst_resm(TWARN, "parent: waitpid() failed."); 137 138 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 139 tst_resm(TWARN, "parent: container was terminated by %s", 140 strsignal(WTERMSIG(status))); 141 142 /* cleanup and exit */ 143 CLEANUP(); 144} /* End main */ 145 146/* 147 * cleanup() - performs all ONE TIME cleanup for this test at 148 * completion or premature exit. 149 */ 150void cleanup() 151{ 152 /* Clean the test testcase as LTP wants*/ 153 TEST_CLEANUP; 154 tst_exit(); 155 /* NOTREACHED */ 156} 157