pidns16.c revision 85576650bc5be0e5a0e339567679bcd5c0e59477
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 17* * Test Assertion. 18* *---------------- 19* * kill -USR1 container_init 20* * - from the parent process and also inside a container 21* * - Where init has defined a custom handler for USR1 22* * - Should call the handler and 23* * - Verify whether the signal handler is called from the proper process. 24* * 25* * Description: 26* * Create PID namespace container. 27* * Container init defines the handler for SIGUSR1 and waits indefinetly. 28* * Parent sends SIGUSR1 to container init. 29* * The signal handler is handled and the cont-init resumes normally. 30* * From the container, again the signal SIGUSR1 is sent. 31* * In the sig-handler check if it's invoked from correct pid(parent/container) 32* * If cont-init wakes up properly - 33* * it will return expected value at exit which is verified at the end. 34* * 35* * History: 36* * DATE NAME DESCRIPTION 37* * 04/11/08 Veerendra C <vechandr@in.ibm.com> Verifying cont init kill -USR1 38* 39*******************************************************************************/ 40#include "config.h" 41 42#define _GNU_SOURCE 1 43#include <stdio.h> 44#include <stdlib.h> 45#include <sys/wait.h> 46#include <sys/types.h> 47#include <signal.h> 48#include <unistd.h> 49#include <usctest.h> 50#include <test.h> 51#include <libclone.h> 52#define CHILD_PID 1 53#define PARENT_PID 0 54 55char *TCID = "pidns16"; 56int TST_TOTAL = 1; 57pid_t globalpid; 58 59/* 60 * cleanup() - performs all ONE TIME cleanup for this test at 61 * completion or premature exit. 62 */ 63void cleanup() 64{ 65 /* Clean the test testcase as LTP wants*/ 66 TEST_CLEANUP; 67 tst_exit(); 68} 69 70void child_signal_handler(int sig, siginfo_t *si, void *unused) 71{ 72 static int c = 1; 73 /* Verifying from which process the signal handler is signalled */ 74 75 if ((c == 1) && (si->si_pid == globalpid)) 76 tst_resm(TINFO, "sig_handler is signalled from pid %d" , 77 globalpid); 78 else if ((c == 2) && (si->si_pid == CHILD_PID)) 79 tst_resm(TINFO, "sig_handler is signalled from pid %d" , 80 CHILD_PID); 81 else 82 tst_resm(TBROK, "Unexpected value for Sending-ProcessID" 83 " when signal handler called %d\n", si->si_pid); 84 c++; 85} 86 87/* 88 * child_fn() - Inside container 89 */ 90int child_fn(void *ttype) 91{ 92 struct sigaction sa; 93 pid_t pid, ppid; 94 95 /* Set process id and parent pid */ 96 pid = getpid(); 97 ppid = getppid(); 98 99 if ((pid != CHILD_PID) || (ppid != PARENT_PID)) 100 tst_resm(TBROK, "pidns is not created."); 101 102 /* Set signal handler for SIGUSR1, also mask other signals */ 103 sa.sa_flags = SA_SIGINFO; 104 sigemptyset(&sa.sa_mask); 105 sa.sa_sigaction = child_signal_handler; 106 if (sigaction(SIGUSR1, &sa, NULL) == -1) 107 tst_resm(TBROK, "%d: sigaction() failed", pid); 108 109 pause(); 110 tst_resm(TINFO, "Container: Resumed after receiving SIGUSR1 " 111 "from parentNS "); 112 if (kill(pid, SIGUSR1) != 0) { 113 tst_resm(TFAIL, "kill(SIGUSR1) fails."); 114 cleanup(); 115 } 116 tst_resm(TINFO, "Container: Resumed after sending SIGUSR1 " 117 "from container itself"); 118 _exit(10); 119} 120 121 122/*********************************************************************** 123* M A I N 124***********************************************************************/ 125int main(int argc, char *argv[]) 126{ 127 int status; 128 pid_t cpid; 129 130 globalpid = getpid(); 131 132 cpid = do_clone(CLONE_NEWPID | SIGCHLD, child_fn, NULL); 133 134 if (cpid < 0) { 135 tst_resm(TBROK, "clone() failed."); 136 cleanup(); 137 } 138 139 sleep(1); 140 if (kill(cpid, SIGUSR1) != 0) { 141 tst_resm(TFAIL, "kill(SIGUSR1) fails."); 142 cleanup(); 143 } 144 sleep(1); 145 if (waitpid(cpid, &status, 0) < 0) 146 tst_resm(TWARN, "waitpid() failed."); 147 148 149 if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 10)) 150 tst_resm(TPASS, "container init continued successfuly, " 151 "after handling signal -USR1\n"); 152 else 153 tst_resm(TFAIL, "c-init failed to continue after " 154 "passing kill -USR1"); 155 cleanup(); 156 return 0; 157} /* End main */ 158