pidns04.c revision df3eb16e38c6a163b0a7367c885679eed6140964
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#define CLEANUP cleanup
62#include "libclone.h"
63
64#define INIT_PID        1
65#define CHILD_PID       1
66#define PARENT_PID      0
67
68char *TCID = "pid_namespace4";
69int TST_TOTAL=1;
70int     fd[2] ;
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, "got unexpected result of cpid=%d ppid=%d",
96				cpid, ppid);
97	}
98	CLEANUP();
99	close(fd[1]);
100	tst_exit();
101}
102
103/***********************************************************************
104*   M A I N
105***********************************************************************/
106
107int main(int argc, char *argv[])
108{
109	int ret, status, nbytes;
110        char    readbuffer[80];
111
112	pipe(fd);
113	ret = do_clone_unshare_test(T_CLONE, CLONE_NEWPID, child_fn1, NULL);
114	if ((wait(&status)) < 0) {
115		tst_resm(TWARN, "wait() failed, skipping this test case");
116		/* Cleanup & continue with next test case */
117		CLEANUP();
118	}
119	if (ret == -1) {
120		tst_resm(TFAIL, "clone() Failed, errno = %d :"
121			" %s", ret, strerror(ret));
122		/* Cleanup & continue with next test case */
123		CLEANUP();
124	}
125
126	/* Parent process closes up write side of pipe */
127	close(fd[1]);
128	/* Read in a string from the pipe */
129	nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
130
131	if (nbytes !=0 ) {
132		tst_resm(TPASS, "Container init : %s", readbuffer);
133	}
134	else {
135		tst_resm(TFAIL, "Container init is killed by SIGKILL !!!");
136	}
137
138	if (WTERMSIG(status)) {
139		tst_resm(TFAIL, "Container init pid got killed by signal %d",
140		WTERMSIG(status));
141	}
142        /* cleanup and exit */
143	CLEANUP();
144	close(fd[0]);
145
146	tst_exit();
147
148}	/* End main */
149
150/*
151 * cleanup() - performs all ONE TIME cleanup for this test at
152 *             completion or premature exit.
153 */
154static void
155cleanup()
156{
157	/* Clean the test testcase as LTP wants*/
158	TEST_CLEANUP;
159}
160