pidns04.c revision c476f1d78738302a452f6b2d0888f8ac42e5763a
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* File: pidns04.c
18*
19* Description:
20*  The pidns04.c testcase builds into the ltp framework to verify
21*  the basic functionality of PID Namespace.
22*
23* Verify that:
24* 1. When parent clone a process with flag CLONE_NEWPID, the process ID of
25* child should be one.
26*
27* 2. When parent clone a process with flag CLONE_NEWPID, the parent process ID
28* of should be zero.
29*
30* 3. The container init process (one), should not get killed by the SIGKILL in
31* the childNS
32*
33* Total Tests:
34*
35* Test Name: pidns04
36*
37* Test Assertion & Strategy:
38*
39* From main() clone a new child process with passing the clone_flag as
40* CLONE_NEWPID.
41* The container init, should not get killed by the SIGKILL inside the child NS.
42* Usage: <for command-line>
43* pidns04
44*
45* History:
46*
47* FLAG DATE     	NAME           		        DESCRIPTION
48* 08/10/08      Veerendra C <vechandr@in.ibm.com> Verifies killing of cont init.
49*
50*******************************************************************************/
51#define _GNU_SOURCE 1
52#include <sys/wait.h>
53#include <assert.h>
54#include <stdio.h>
55#include <stdlib.h>
56#include <unistd.h>
57#include <string.h>
58#include <errno.h>
59#include <usctest.h>
60#include <test.h>
61#include <libclone.h>
62
63#define INIT_PID        1
64#define CHILD_PID       1
65#define PARENT_PID      0
66
67char *TCID = "pid_namespace4";
68int TST_TOTAL=1;
69int     fd[2] ;
70void cleanup(void);
71
72/*
73 * child_fn1() - Inside container
74*/
75static int child_fn1(void *ttype)
76{
77	pid_t cpid, ppid;
78	cpid = getpid();
79	ppid = getppid();
80	char mesg[] = "I was not killed !";
81       	/* Child process closes up read side of pipe */
82       	close(fd[0]);
83
84	/* Comparing the values to make sure pidns is created correctly */
85	if(( cpid == CHILD_PID) && ( ppid == PARENT_PID ) ) {
86		tst_resm(TINFO, "PIDNS test is running inside container");
87		kill(INIT_PID, SIGKILL);
88		/* Verifying whether the container init is not killed, "
89		 If so writing into the pipe created in the parent NS" */
90
91        	/* Send "mesg" through the write side of pipe */
92        	write(fd[1], mesg, (strlen(mesg)+1));
93	}
94	else {
95		tst_resm(TFAIL, "FAIL: Got unexpected result of"
96		" cpid=%d ppid=%d\n", cpid, ppid);
97	}
98	close(fd[1]);
99	cleanup();
100
101	/* NOT REACHED */
102	return 0;
103}
104
105/***********************************************************************
106*   M A I N
107***********************************************************************/
108
109int main(int argc, char *argv[])
110{
111	int ret, status, nbytes;
112        char    readbuffer[80];
113
114	pipe(fd);
115	ret = do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn1, NULL);
116	if ((wait(&status)) < 0) {
117		tst_resm(TWARN, "wait() failed, skipping this test case");
118		/* Cleanup & continue with next test case */
119		cleanup();
120	}
121	if (ret == -1) {
122		tst_resm(TFAIL, "clone() Failed, errno = %d :"
123			" %s", ret, strerror(ret));
124		/* Cleanup & continue with next test case */
125		cleanup();
126	}
127
128	/* Parent process closes up write side of pipe */
129	close(fd[1]);
130	/* Read in a string from the pipe */
131	nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
132
133	if (nbytes !=0 ) {
134		tst_resm(TPASS, "Container init : %s", readbuffer);
135	}
136	else {
137		tst_resm(TFAIL, "Container init is killed by SIGKILL !!!");
138	}
139
140	if (WTERMSIG(status)) {
141		tst_resm(TFAIL, "Container init pid got killed by signal %d",
142		WTERMSIG(status));
143	}
144        /* cleanup and exit */
145	cleanup();
146	close(fd[0]);
147
148	/*NOTREACHED*/
149	return 0;
150
151}	/* End main */
152
153/*
154 * cleanup() - performs all ONE TIME cleanup for this test at
155 *             completion or premature exit.
156 */
157void
158cleanup()
159{
160	/* Clean the test testcase as LTP wants*/
161	TEST_CLEANUP;
162
163	/* exit with return code appropriate for results */
164	tst_exit();
165}
166