/* * Copyright (c) International Business Machines Corp., 2007 * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** * * Test Assertion. * *---------------- * * kill -USR1 container_init * * - from the parent process and also inside a container * * - Where init has defined a custom handler for USR1 * * - Should call the handler and * * - Verify whether the signal handler is called from the proper process. * * * * Description: * * Create PID namespace container. * * Container init defines the handler for SIGUSR1 and waits indefinetly. * * Parent sends SIGUSR1 to container init. * * The signal handler is handled and the cont-init resumes normally. * * From the container, again the signal SIGUSR1 is sent. * * In the sig-handler check if it's invoked from correct pid(parent/container) * * If cont-init wakes up properly - * * it will return expected value at exit which is verified at the end. * * * * History: * * DATE NAME DESCRIPTION * * 04/11/08 Veerendra C Verifying cont init kill -USR1 * *******************************************************************************/ #include "config.h" #define _GNU_SOURCE 1 #include #include #include #include #include #include #include "pidns_helper.h" #include "test.h" #define CHILD_PID 1 #define PARENT_PID 0 char *TCID = "pidns16"; int TST_TOTAL = 3; void child_signal_handler(int sig, siginfo_t * si, void *unused) { static int c = 1; pid_t expected_pid; /* Verifying from which process the signal handler is signalled */ switch (c) { case 1: expected_pid = PARENT_PID; break; case 2: expected_pid = CHILD_PID; break; default: tst_resm(TBROK, "child should NOT be signalled 3+ times"); return; } if (si->si_pid == expected_pid) tst_resm(TPASS, "child is signalled from expected pid %d", expected_pid); else tst_resm(TFAIL, "child is signalled from unexpected pid %d," " expecting pid %d", si->si_pid, expected_pid); c++; } /* * child_fn() - Inside container */ int child_fn(void *ttype) { struct sigaction sa; pid_t pid, ppid; /* Set process id and parent pid */ pid = getpid(); ppid = getppid(); if ((pid != CHILD_PID) || (ppid != PARENT_PID)) tst_resm(TBROK, "pidns is not created."); /* Set signal handler for SIGUSR1, also mask other signals */ sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = child_signal_handler; if (sigaction(SIGUSR1, &sa, NULL) == -1) tst_resm(TBROK, "%d: sigaction() failed", pid); pause(); tst_resm(TINFO, "Container: Resumed after receiving SIGUSR1 " "from parentNS "); if (kill(pid, SIGUSR1) != 0) { tst_resm(TFAIL, "kill(SIGUSR1) fails."); } tst_resm(TINFO, "Container: Resumed after sending SIGUSR1 " "from container itself"); _exit(10); } static void setup(void) { tst_require_root(); check_newpid(); } /*********************************************************************** * M A I N ***********************************************************************/ int main(int argc, char *argv[]) { int status; pid_t cpid; setup(); cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); if (cpid < 0) { tst_resm(TBROK, "clone() failed."); } sleep(1); if (kill(cpid, SIGUSR1) != 0) { tst_resm(TFAIL, "kill(SIGUSR1) fails."); } sleep(1); if (waitpid(cpid, &status, 0) < 0) tst_resm(TWARN, "waitpid() failed."); if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 10)) tst_resm(TPASS, "container init continued successfuly, " "after handling signal -USR1"); else tst_resm(TFAIL, "c-init failed to continue after " "passing kill -USR1"); tst_exit(); }