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