pidns16.c revision 354ebb48db8e66a853a58379a4808d5dcd1ceac3
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 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* M A I N 123***********************************************************************/ 124int main(int argc, char *argv[]) 125{ 126 int status; 127 pid_t cpid; 128 129 globalpid = getpid(); 130 131 cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); 132 133 if (cpid < 0) { 134 tst_resm(TBROK, "clone() failed."); 135 cleanup(); 136 } 137 138 sleep(1); 139 if (kill(cpid, SIGUSR1) != 0) { 140 tst_resm(TFAIL, "kill(SIGUSR1) fails."); 141 cleanup(); 142 } 143 sleep(1); 144 if (waitpid(cpid, &status, 0) < 0) 145 tst_resm(TWARN, "waitpid() failed."); 146 147 if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 10)) 148 tst_resm(TPASS, "container init continued successfuly, " 149 "after handling signal -USR1\n"); 150 else 151 tst_resm(TFAIL, "c-init failed to continue after " 152 "passing kill -USR1"); 153 cleanup(); 154 tst_exit(); 155} 156