On Tue, 2008-12-16 at 10:49 +0530, gowrishankar wrote: > Hi Subrata, > Please accept below testcase patches for pid namespace. > > Thanks, > Gowri > --- > pidns12: > Description: > The pidns12.c testcase verifies that siginfo->si_pid is set to 0 > if sender (parent process) is not in receiver's namespace. > > pidns13: > The pidns13.c testcase checks container init, for async I/O > triggered by peer namespace process. > > pidns17: > The pidns17.c testcase verifies inside the container, if kill(-1, SIGUSR1) > terminates all children running inside. > > Signed-off-by: Gowrishankar M <[email protected]>
Thanks. Added. Regards-- Subrata > Acked-by: Sukadev Bhattiprolu <[email protected]> > > > plain text document attachment (pidns12-v2.patch) > Index: ltp/testcases/kernel/containers/pidns/pidns12.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ ltp/testcases/kernel/containers/pidns/pidns12.c 2008-12-15 > 22:36:45.000000000 -0500 > @@ -0,0 +1,216 @@ > +/* > +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +* > +*************************************************************************** > +* File: pidns12.c > +* * > +* * Description: > +* * The pidns12.c testcase verifies that siginfo->si_pid is set to 0 > +* * if sender (parent process) is not in receiver's namespace. > +* * > +* * Test Assertion & Strategy: > +* * Create a PID namespace container. > +* * Initialise signal handler for SIGUSR1 in container. > +* * Let parent send SIGUSR1 to container. > +* * Check if sender pid is set to 0 from signal info. > +* * > +* * Usage: <for command-line> > +* * pidns12 > +* * > +* * History: > +* * DATE NAME DESCRIPTION > +* * 13/11/08 Gowrishankar M Creation of this test. > +* * <[email protected]> > +* > +******************************************************************************/ > +#define _GNU_SOURCE 1 > +#include <sys/wait.h> > +#include <sys/types.h> > +#include <signal.h> > +#include <string.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <stdio.h> > +#include <usctest.h> > +#include <test.h> > +#include <libclone.h> > + > +char *TCID = "pidns12"; > +int TST_TOTAL = 1; > +int errno; > +int pipefd[2]; > + > +#define CHILD_PID 1 > +#define PARENT_PID 0 > + > +/* > + * cleanup() - performs all ONE TIME cleanup for this test at > + * completion or premature exit. > + */ > +void cleanup() > +{ > + /* Clean the test testcase as LTP wants*/ > + TEST_CLEANUP; > + > + /* exit with return code appropriate for results */ > + tst_exit(); > +} > + > +/* > + * child_signal_handler() - dummy function for sigaction() > + */ > +static void child_signal_handler(int sig, siginfo_t *si, void *unused) > +{ > + /* sigtimedwait() traps siginfo details, so this wont be called */ > + tst_resm(TWARN, "cinit: control should have not reached here!"); > +} > + > +/* > + * child_fn() - Inside container > + */ > +int child_fn(void *arg) > +{ > + struct sigaction sa; > + sigset_t newset; > + siginfo_t info; > + struct timespec timeout; > + pid_t pid, ppid; > + > + /* Set process id and parent pid */ > + pid = getpid(); > + ppid = getppid(); > + if (pid != CHILD_PID || ppid != PARENT_PID) { > + tst_resm(TBROK, "cinit: pidns is not created."); > + cleanup(); > + } > + > + /* Close read end of pipe */ > + close(pipefd[0]); > + > + /* Set signal handler for SIGUSR1 */ > + sa.sa_flags = SA_SIGINFO; > + sigfillset(&sa.sa_mask); > + sa.sa_sigaction = child_signal_handler; > + if (sigaction(SIGUSR1, &sa, NULL) == -1) { > + tst_resm(TBROK, "cinit: sigaction() failed(%s).",\ > + strerror(errno)); > + cleanup(); > + } > + > + /* Set timeout for sigtimedwait */ > + timeout.tv_sec = 3; > + timeout.tv_nsec = 0; > + > + /* Set mask to wait for SIGUSR1 signal */ > + sigemptyset(&newset); > + sigaddset(&newset, SIGUSR1); > + > + /* Let parent to signal SIGUSR1 */ > + if (write(pipefd[1], "c:go\0", 5) != 5) { > + tst_resm(TBROK, "cinit: pipe is broken to write"); > + cleanup(); > + } > + > + /* Wait for SIGUSR1 */ > + if (sigtimedwait(&newset, &info, &timeout) != SIGUSR1) { > + tst_resm(TBROK, "cinit: sigtimedwait() failed(%s).", > + strerror(errno)); > + cleanup(); > + } > + > + /* Recieved SIGUSR1. Check sender pid */ > + if (info.si_pid == 0) > + tst_resm(TPASS, "cinit: signalling PID (from other namespace)"\ > + " is 0 as expected"); > + else > + tst_resm(TFAIL, "cinit: signalling PID (from other namespace)"\ > + " is not 0, but %d.", info.si_pid); > + > + /* cleanup and exit */ > + close(pipefd[1]); > + cleanup(); > + > + /* Control won't reach below */ > + exit(0); > +} > + > + > +/*********************************************************************** > +* M A I N > +***********************************************************************/ > + > +int main(int argc, char *argv[]) > +{ > + int status, stack_size=getpagesize() * 4; > + void *stack = malloc (stack_size); > + void *childstack; > + pid_t pid, cpid; > + char buf[5]; > + > + pid = getpid(); > + tst_resm(TINFO, "parent: PID is %d", pid); > + > + /* Create pipe for intercommunication */ > + if (pipe(pipefd) == -1) { > + tst_resm(TBROK, "parent: pipe() failed. aborting!"); > + cleanup(); > + } > + > + /* Container creation on PID namespace */ > + if (!stack) { > + tst_resm(TBROK, "parent: stack creation failed."); > + cleanup(); > + } > + > + childstack = stack + stack_size; > + > + cpid = clone(child_fn, childstack, CLONE_NEWPID|SIGCHLD, NULL); > + if (cpid < 0) { > + tst_resm(TBROK, "parent: clone() failed(%s).",\ > + strerror(errno)); > + cleanup(); > + } > + > + /* Close write end of pipe */ > + close(pipefd[1]); > + > + /* Check if container is ready */ > + read(pipefd[0], buf, 5); > + if (strcmp(buf, "c:go") != 0) { > + tst_resm(TBROK, "parent: container did not respond!"); > + cleanup(); > + } > + > + /* Send SIGUSR1 to container init */ > + if (kill(cpid, SIGUSR1) == -1) { > + tst_resm(TBROK, "parent: kill() failed(%s).", strerror(errno)); > + cleanup(); > + } > + > + if (waitpid(cpid, &status, 0) < 0) > + tst_resm(TWARN, "parent: waitpid() failed(%s).",\ > + strerror(errno)); > + > + if (WIFSIGNALED(status) && WTERMSIG(status)) > + tst_resm(TBROK, "child is terminated by signal(%s)",\ > + strsignal(WTERMSIG(status))); > + > + /* Cleanup and exit */ > + close(pipefd[0]); > + cleanup(); > + > + /* Control won't reach below */ > + exit(0); > + > +} /* End main */ > Index: ltp/testcases/kernel/containers/pidns/runpidnstest.sh > =================================================================== > --- ltp.orig/testcases/kernel/containers/pidns/runpidnstest.sh > 2008-12-12 06:20:10.000000000 -0500 > +++ ltp/testcases/kernel/containers/pidns/runpidnstest.sh 2008-12-15 > 22:38:34.000000000 -0500 > @@ -61,6 +61,12 @@ > err_code=$rc > fi > > +pidns12 > +rc=$? > +if [ $rc -ne 0 ] && [ -z $err_code ]; then > + err_code=$rc > +fi > + > # If any test failed then exit with the value error-code. > if ! [ -z $err_code ]; then > exit $err_code > plain text document attachment (pidns13-v2.patch) > Index: ltp/testcases/kernel/containers/pidns/pidns13.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ ltp/testcases/kernel/containers/pidns/pidns13.c 2008-12-15 > 23:00:56.000000000 -0500 > @@ -0,0 +1,258 @@ > +/* > +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +* > +*************************************************************************** > +* File: pidns13.c > +* * > +* * Description: > +* * The pidns13.c testcase checks container init, for async I/O > +* * triggered by peer namespace process. > +* * > +* * Test Assertion & Strategy: > +* * Create a pipe in parent namespace. > +* * Create two PID namespace containers(cinit1 and cinit2). > +* * In cinit1, set pipe read end to send SIGUSR1. > +* * for asynchronous I/O. > +* * Let cinit2 to trigger async I/O on pipe write end. > +* * In signal info, check si_code to be POLL_IN and si_fd to be pipe read > fd. > +* * > +* * Usage: <for command-line> > +* * pidns13 > +* * > +* * History: > +* * DATE NAME DESCRIPTION > +* * 23/10/08 Gowrishankar M Created test scenarion. > +* * <[email protected]> > +* > +******************************************************************************/ > +#define _GNU_SOURCE 1 > +#include <sys/wait.h> > +#include <sys/types.h> > +#include <fcntl.h> > +#include <signal.h> > +#include <string.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <stdio.h> > +#include <usctest.h> > +#include <test.h> > +#include <libclone.h> > + > +char *TCID = "pidns13"; > +int TST_TOTAL = 1; > +int pipe_fd[2]; > + > +#define CHILD_PID 1 > +#define PARENT_PID 0 > + > +/* > + * cleanup() - performs all ONE TIME cleanup for this test at > + * completion or premature exit. > + */ > +void cleanup() > +{ > + /* Clean the test testcase as LTP wants*/ > + TEST_CLEANUP; > + > + /* exit with return code appropriate for results */ > + tst_exit(); > +} > + > +/* > + * child_signal_handler() - dummy function for sigaction() > + */ > +static void child_signal_handler(int sig, siginfo_t *si, void *unused) > +{ > + /* sigtimedwait() traps siginfo details, so this wont be called */ > + tst_resm(TWARN, "cinit(pid %d): control should have not reached here!",\ > + getpid()); > +} > + > +/* > + * child_fn() - Inside container > + */ > +int child_fn(void *arg) > +{ > + struct sigaction sa; > + sigset_t newset; > + siginfo_t info; > + struct timespec timeout; > + pid_t pid, ppid; > + int cinit_no = *((int *)arg); > + > + /* Set process id and parent pid */ > + pid = getpid(); > + ppid = getppid(); > + if (pid != CHILD_PID || ppid != PARENT_PID) { > + tst_resm(TBROK, "cinit%d: pidns is not created.",\ > + cinit_no); > + cleanup(); > + } > + > + if (cinit_no == 1) { > + /* in container 1 */ > + /* close pipe write descriptor */ > + if (close(pipe_fd[1]) == -1) { > + tst_resm(TBROK, "cinit1: close(pipe_fd[1]) failed"); > + cleanup(); > + } > + > + /* Let cinit1 to get SIGUSR1 on I/O availability */ > + if (fcntl(pipe_fd[0], F_SETOWN, pid) == -1) { > + tst_resm(TBROK, "cinit1: fcntl(F_SETOWN) failed"); > + cleanup(); > + } > + > + if (fcntl(pipe_fd[0], F_SETSIG, SIGUSR1) == -1) { > + tst_resm(TBROK, "cinit1: fcntl(F_SETSIG) failed"); > + cleanup(); > + } > + > + if (fcntl(pipe_fd[0], F_SETFL,\ > + fcntl(pipe_fd[0], F_GETFL)|O_ASYNC) == -1) { > + tst_resm(TBROK, "cinit1: fcntl(F_SETFL) failed"); > + cleanup(); > + } > + > + /* Set signal handler for SIGUSR1, also mask other signals */ > + sa.sa_flags = SA_SIGINFO; > + sigfillset(&sa.sa_mask); > + sa.sa_sigaction = child_signal_handler; > + if (sigaction(SIGUSR1, &sa, NULL) == -1) { > + tst_resm(TBROK, "cinit1: sigaction() failed"); > + cleanup(); > + } > + > + tst_resm(TINFO, "cinit1: setup handler for async I/O on pipe"); > + > + /* Set timeout for sigtimedwait */ > + timeout.tv_sec = 10; > + timeout.tv_nsec = 0; > + > + /* Set mask to wait for SIGUSR1 signal */ > + sigemptyset(&newset); > + sigaddset(&newset, SIGUSR1); > + > + /* Wait for SIGUSR1 */ > + if (sigtimedwait(&newset, &info, &timeout) != SIGUSR1) { > + tst_resm(TBROK, "cinit1: sigtimedwait() failed."); > + cleanup(); > + } > + > + /* Recieved SIGUSR1. Check details. */ > + if (info.si_fd == pipe_fd[0] && info.si_code == POLL_IN ) > + tst_resm(TPASS, "cinit1: si_fd is %d, si_code is %d",\ > + info.si_fd, info.si_code); > + else > + tst_resm(TFAIL, "cinit1: si_fd is %d, si_code is %d",\ > + info.si_fd, info.si_code); > + > + /* all done, close the descriptors opened */ > + close(pipe_fd[0]); > + > + } else { > + /* in container 2 */ > + /* close pipe read descriptor */ > + if (close(pipe_fd[0]) == -1) { > + tst_resm(TBROK, "cinit2: close(pipe_fd[0]) failed"); > + cleanup(); > + } > + > + /* sleep for few seconds to avoid race with cinit1 */ > + sleep(2); > + > + /* Write some data in pipe to SIGUSR1 cinit1 */ > + tst_resm(TINFO, "cinit2: writing some data in pipe"); > + if (write(pipe_fd[1], "test\n", 5) == -1) { > + tst_resm(TBROK, "cinit2: write() failed"); > + cleanup(); > + } > + > + /* all done, close the descriptors opened */ > + close(pipe_fd[1]); > + } > + > + /* cleanup and exit */ > + cleanup(); > + exit(0); > +} > + > + > +/*********************************************************************** > +* M A I N > +***********************************************************************/ > + > +int main(int argc, char *argv[]) > +{ > + int status, stack_size=getpagesize() * 4; > + int *cinit_no; > + void *stack1 = malloc(stack_size); > + void *stack2 = malloc(stack_size); > + void *childstack1, *childstack2; > + pid_t cpid1, cpid2; > + > + /* create pipe */ > + if (pipe(pipe_fd) == -1) { > + tst_resm(TBROK, "parent: pipe creation failed"); > + cleanup(); > + } > + > + /* container creation on PID namespace */ > + if (!stack1 || !stack2) { > + tst_resm(TBROK, "parent: stack creation failed."); > + cleanup(); > + } > + > + childstack1 = stack1 + stack_size; > + childstack2 = stack2 + stack_size; > + > + /* Create container 1 */ > + *cinit_no = 1; > + cpid1 = clone(child_fn, childstack1, CLONE_NEWPID|SIGCHLD, cinit_no); > + > + /* Create container 2 */ > + *cinit_no = 2; > + cpid2 = clone(child_fn, childstack2, CLONE_NEWPID|SIGCHLD, cinit_no); > + if (cpid1 < 0 || cpid2 < 0) { > + tst_resm(TBROK, "parent: clone() failed."); > + cleanup(); > + } > + > + /* Close unwanted descriptors */ > + close(pipe_fd[0]); > + close(pipe_fd[1]); > + > + /* Wait for containers to exit */ > + if (waitpid(cpid2, &status, 0) < 0) > + tst_resm(TWARN, "parent: waitpid(cpid2) failed."); > + > + if (WIFSIGNALED(status) && WTERMSIG(status)) > + tst_resm(TWARN, "parent: cinit2 is terminated by signal(%s)",\ > + strsignal(WTERMSIG(status))); > + > + if (waitpid(cpid1, &status, 0) < 0) > + tst_resm(TWARN, "parent: waitpid(cpid1) failed."); > + > + if (WIFSIGNALED(status) && WTERMSIG(status)) > + tst_resm(TWARN, "parent: cinit1 is terminated by signal(%s)",\ > + strsignal(WTERMSIG(status))); > + > + /* Cleanup and exit */ > + cleanup(); > + > + /* Control won't reach below */ > + exit(0); > + > +} /* End main */ > + > Index: ltp/testcases/kernel/containers/pidns/runpidnstest.sh > =================================================================== > --- ltp.orig/testcases/kernel/containers/pidns/runpidnstest.sh > 2008-12-15 22:38:34.000000000 -0500 > +++ ltp/testcases/kernel/containers/pidns/runpidnstest.sh 2008-12-15 > 22:58:49.000000000 -0500 > @@ -67,6 +67,12 @@ > err_code=$rc > fi > > +pidns13 > +rc=$? > +if [ $rc -ne 0 ] && [ -z $err_code ]; then > + err_code=$rc > +fi > + > # If any test failed then exit with the value error-code. > if ! [ -z $err_code ]; then > exit $err_code > plain text document attachment (pidns17-v1.patch) > Index: ltp/testcases/kernel/containers/pidns/pidns17.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ ltp/testcases/kernel/containers/pidns/pidns17.c 2008-12-15 > 23:54:00.000000000 -0500 > @@ -0,0 +1,151 @@ > +/* > +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +* > +*************************************************************************** > +* File: pidns17.c > +* * > +* * Description: > +* * The pidns17.c testcase verifies inside the container, if kill(-1, > SIGUSR1) > +* * terminates all children running inside. > +* * > +* * Test Assertion & Strategy: > +* * Create a PID namespace container. > +* * Spawn many children inside it. > +* * Invoke kill(-1, SIGUSR1) inside container and check if it terminates > +* * all children. > +* * > +* * Usage: <for command-line> > +* * pidns17 > +* * > +* * History: > +* * DATE NAME DESCRIPTION > +* * 13/11/08 Gowrishankar M Creation of this test. > +* * <[email protected]> > +* > +******************************************************************************/ > +#define _GNU_SOURCE 1 > +#include <sys/wait.h> > +#include <sys/types.h> > +#include <string.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <stdio.h> > +#include <errno.h> > +#include <usctest.h> > +#include <test.h> > +#include <libclone.h> > + > +char *TCID = "pidns17"; > +int TST_TOTAL = 1; > +int errno; > + > +int child_fn(void *); > +void cleanup(void); > + > +#define CHILD_PID 1 > +#define PARENT_PID 0 > + > +/* > + * child_fn() - Inside container > + */ > +int child_fn(void *arg) > +{ > + pid_t pid, ppid; > + int i, children[10], status; > + > + /* Set process id and parent pid */ > + pid = getpid(); > + ppid = getppid(); > + if (pid != CHILD_PID || ppid != PARENT_PID) { > + tst_resm(TBROK, "cinit: pidns is not created."); > + cleanup(); > + } > + > + /* Spawn many children */ > + for (i = 0; i < 10; i++) > + if ((children[i] = fork()) == 0) > + sleep(10); > + > + /* wait for last child to get scheduled */ > + sleep(1); > + > + if (kill(-1, SIGUSR1) == -1) { > + tst_resm(TBROK, "cinit: kill(-1, SIGUSR1) failed"); > + cleanup(); > + } > + > + for (i = 0; i < 10; i++) { > + if (waitpid(children[i], &status, WNOHANG) == -1) { > + tst_resm(TBROK, "cinit: waitpid() failed(%s)",\ > + strerror(errno)); > + cleanup(); > + } > + if (!(WIFSIGNALED(&status) && WTERMSIG(status) == SIGUSR1)) { > + tst_resm(TFAIL, "cinit: found a child alive still."); > + cleanup(); > + } > + } > + tst_resm(TPASS, "cinit: all children are terminated."); > + > + /* cleanup and exit */ > + cleanup(); > + exit(0); > +} > + > +/*********************************************************************** > +* M A I N > +***********************************************************************/ > + > +int main(int argc, char *argv[]) > +{ > + int status, ret; > + pid_t pid; > + > + pid = getpid(); > + > + /* Container creation on PID namespace */ > + ret = do_clone_unshare_test(T_CLONE,\ > + CLONE_NEWPID, child_fn, NULL); > + if (ret != 0) { > + tst_resm(TBROK, "parent: clone() failed. rc=%d(%s)",\ > + ret, strerror(errno)); > + /* Cleanup & continue with next test case */ > + cleanup(); > + } > + > + sleep(1); > + if (wait(&status) < 0) > + tst_resm(TWARN, "parent: waitpid() failed."); > + > + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) > + tst_resm(TWARN, "parent: container was terminated by %s",\ > + strsignal(WTERMSIG(status))); > + > + /* cleanup and exit */ > + cleanup(); > + exit(0); > +} /* End main */ > + > +/* > + * cleanup() - performs all ONE TIME cleanup for this test at > + * completion or premature exit. > + */ > +void cleanup() > +{ > + /* Clean the test testcase as LTP wants*/ > + TEST_CLEANUP; > + > + /* exit with return code appropriate for results */ > + tst_exit(); > +} > Index: ltp/testcases/kernel/containers/pidns/runpidnstest.sh > =================================================================== > --- ltp.orig/testcases/kernel/containers/pidns/runpidnstest.sh > 2008-12-15 22:58:49.000000000 -0500 > +++ ltp/testcases/kernel/containers/pidns/runpidnstest.sh 2008-12-15 > 23:54:36.000000000 -0500 > @@ -73,6 +73,12 @@ > err_code=$rc > fi > > +pidns17 > +rc=$? > +if [ $rc -ne 0 ] && [ -z $err_code ]; then > + err_code=$rc > +fi > + > # If any test failed then exit with the value error-code. > if ! [ -z $err_code ]; then > exit $err_code ------------------------------------------------------------------------------ SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
