blob: 0b4e6c80f83f169a49705b90ef2dfa4fd61711cb [file] [log] [blame]
subrata_modak88af3352008-11-27 15:33:55 +00001/*
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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080013* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
subrata_modak88af3352008-11-27 15:33:55 +000014*
15***************************************************************************
16*
17* Assertion:
18* a) Create a container.
19* b) Create many levels of child containers inside this container.
20* c) Now do kill -9 init , outside of the container.
21* d) This should kill all the child containers.
22* (containers created at the level below)
23*
24* Description:
25* 1. Parent process clone a process with flag CLONE_NEWPID
26* 2. The container will recursively loop and creates 4 more containers.
27* 3. All the container init's goes into sleep(), waiting to be terminated.
28* 4. The parent process will kill child[3] by passing SIGKILL
29* 5. Now parent process, verifies the child containers 4 & 5 are destroyed.
30* 6. If they are killed then
Garrett Cooperad14e902010-12-16 10:03:44 -080031* Test passed
32* else Test failed.
subrata_modak88af3352008-11-27 15:33:55 +000033*
34* Test Name: pidns05
35*
36* History:
37*
Monson Shao45192242013-01-08 11:34:44 +080038* FLAG DATE NAME DESCRIPTION
39* 31/10/08 Veerendra C <vechandr@in.ibm.com> Verifies killing of NestedCont's
subrata_modak88af3352008-11-27 15:33:55 +000040*
41*******************************************************************************/
42#define _GNU_SOURCE 1
43#include <sys/wait.h>
44#include <assert.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <unistd.h>
48#include <string.h>
49#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080050#include "test.h"
subrata_modak88af3352008-11-27 15:33:55 +000051#include <libclone.h>
Jan Stanceked991ae2014-07-29 10:50:27 +020052#include "pidns_helper.h"
subrata_modak88af3352008-11-27 15:33:55 +000053
54#define INIT_PID 1
55#define CINIT_PID 1
56#define PARENT_PID 0
57#define MAX_DEPTH 5
58
59char *TCID = "pidns05";
60int TST_TOTAL = 1;
61int fd[2];
62
Wanlong Gao354ebb42012-12-07 10:10:04 +080063void cleanup(void)
subrata_modak88af3352008-11-27 15:33:55 +000064{
subrata_modak88af3352008-11-27 15:33:55 +000065}
Garrett Cooperad14e902010-12-16 10:03:44 -080066
67int max_pid(void)
subrata_modak88af3352008-11-27 15:33:55 +000068{
69 FILE *fp;
70 int ret;
71
Wanlong Gao354ebb42012-12-07 10:10:04 +080072 fp = fopen("/proc/sys/kernel/pid_max", "r");
subrata_modak88af3352008-11-27 15:33:55 +000073 if (fp != NULL) {
74 fscanf(fp, "%d", &ret);
75 fclose(fp);
76 } else {
Monson Shao45192242013-01-08 11:34:44 +080077 tst_resm(TBROK, "Cannot open /proc/sys/kernel/pid_max");
subrata_modak88af3352008-11-27 15:33:55 +000078 ret = -1;
79 }
80 return ret;
81}
82
83/* find_cinit_pids() iteratively finds the pid's having same PGID as its parent.
84 * Input parameter - Accepts pointer to pid_t : To copy the pid's matching.
85 * Returns - the number of pids matched.
86*/
Wanlong Gao354ebb42012-12-07 10:10:04 +080087int find_cinit_pids(pid_t * pids)
subrata_modak88af3352008-11-27 15:33:55 +000088{
Wanlong Gao354ebb42012-12-07 10:10:04 +080089 int next = 0, pid_max, i;
subrata_modak88af3352008-11-27 15:33:55 +000090 pid_t parentpid, pgid, pgid2;
91
92 pid_max = max_pid();
93 parentpid = getpid();
94 pgid = getpgid(parentpid);
95
96 /* The loop breaks, when the loop counter reaches the parentpid value */
97 for (i = parentpid + 1; i != parentpid; i++) {
98 if (i > pid_max)
99 i = 2;
100
101 pgid2 = getpgid(i);
102 if (pgid2 == pgid) {
103 pids[next] = i;
104 next++;
105 }
106 }
107 return next;
108}
109
110/*
111* create_nested_container() Recursively create MAX_DEPTH nested containers
112*/
113int create_nested_container(void *vtest)
114{
Garrett Cooperad14e902010-12-16 10:03:44 -0800115 int exit_val;
116 int ret, count, *level;
subrata_modak88af3352008-11-27 15:33:55 +0000117 pid_t cpid, ppid;
118 cpid = getpid();
119 ppid = getppid();
120 char mesg[] = "Nested Containers are created";
121
122 level = (int *)vtest;
123 count = *level;
124
125 /* Child process closes up read side of pipe */
126 close(fd[0]);
127
128 /* Comparing the values to make sure pidns is created correctly */
Garrett Cooperad14e902010-12-16 10:03:44 -0800129 if (cpid != CINIT_PID || ppid != PARENT_PID) {
130 printf("Got unexpected cpid and/or ppid (cpid=%d ppid=%d)\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800131 cpid, ppid);
Garrett Cooperad14e902010-12-16 10:03:44 -0800132 exit_val = 1;
subrata_modak88af3352008-11-27 15:33:55 +0000133 }
134 if (count > 1) {
135 count--;
136 ret = do_clone_unshare_test(T_CLONE, CLONE_NEWPID,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800137 create_nested_container,
138 (void *)&count);
subrata_modak88af3352008-11-27 15:33:55 +0000139 if (ret == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800140 printf("clone failed; errno = %d : %s\n",
141 ret, strerror(ret));
Garrett Cooperad14e902010-12-16 10:03:44 -0800142 exit_val = 1;
143 } else
144 exit_val = 0;
subrata_modak88af3352008-11-27 15:33:55 +0000145 } else {
146 /* Sending mesg, 'Nested containers created' through the pipe */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800147 write(fd[1], mesg, (strlen(mesg) + 1));
Garrett Cooperad14e902010-12-16 10:03:44 -0800148 exit_val = 0;
subrata_modak88af3352008-11-27 15:33:55 +0000149 }
150
151 close(fd[1]);
152 pause();
153
Garrett Cooperad14e902010-12-16 10:03:44 -0800154 return exit_val;
subrata_modak88af3352008-11-27 15:33:55 +0000155}
156
subrata_modak88af3352008-11-27 15:33:55 +0000157void kill_nested_containers()
158{
159 int orig_count, new_count, status = 0, i;
160 pid_t pids[MAX_DEPTH];
161 pid_t pids_new[MAX_DEPTH];
162
163 orig_count = find_cinit_pids(pids);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800164 kill(pids[MAX_DEPTH - 3], SIGKILL);
subrata_modak88af3352008-11-27 15:33:55 +0000165 sleep(1);
166
167 /* After killing child container, getting the New PID list */
168 new_count = find_cinit_pids(pids_new);
169
Wanlong Gao354ebb42012-12-07 10:10:04 +0800170 /* Verifying that the child containers were destroyed when parent is killed */
subrata_modak88af3352008-11-27 15:33:55 +0000171 if (orig_count - 2 != new_count)
172 status = -1;
173
174 for (i = 0; i < new_count; i++) {
175 if (pids[i] != pids_new[i])
176 status = -1;
177 }
178
179 if (status == 0)
Monson Shao45192242013-01-08 11:34:44 +0800180 tst_resm(TPASS, "The number of containers killed are %d",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800181 orig_count - new_count);
subrata_modak88af3352008-11-27 15:33:55 +0000182 else
183 tst_resm(TFAIL, "Failed to kill the sub-containers of "
Monson Shao45192242013-01-08 11:34:44 +0800184 "the container %d", pids[MAX_DEPTH - 3]);
subrata_modak88af3352008-11-27 15:33:55 +0000185
Garrett Cooperad14e902010-12-16 10:03:44 -0800186 /* Loops through the containers created to exit from sleep() */
subrata_modak88af3352008-11-27 15:33:55 +0000187 for (i = 0; i < MAX_DEPTH; i++) {
Peng Haitao02fa9302011-04-04 10:45:40 +0800188 kill(pids[i], SIGKILL);
189 waitpid(pids[i], &status, 0);
subrata_modak88af3352008-11-27 15:33:55 +0000190 }
191}
192
Jan Stanceked991ae2014-07-29 10:50:27 +0200193static void setup(void)
194{
195 tst_require_root(NULL);
196 check_newpid();
197}
198
subrata_modak88af3352008-11-27 15:33:55 +0000199int main(int argc, char *argv[])
200{
201 int ret, nbytes, status;
202 char readbuffer[80];
203 pid_t pid, pgid;
204 int count = MAX_DEPTH;
205
Jan Stanceked991ae2014-07-29 10:50:27 +0200206 setup();
207
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800208 /*
Garrett Cooperad14e902010-12-16 10:03:44 -0800209 * XXX (garrcoop): why in the hell is this fork-wait written this way?
210 * This doesn't add up with the pattern used for the rest of the tests,
211 * so I'm pretty damn sure this test is written incorrectly.
212 */
subrata_modak88af3352008-11-27 15:33:55 +0000213 pid = fork();
Garrett Cooperad14e902010-12-16 10:03:44 -0800214 if (pid == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800215 tst_brkm(TBROK | TERRNO, NULL, "fork failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800216 } else if (pid != 0) {
217 /*
218 * NOTE: use waitpid so that we know we're waiting for the
219 * _top-level_ child instead of a spawned subcontainer.
220 *
221 * XXX (garrcoop): Might want to mask SIGCHLD in the top-level
222 * child too, or not *shrugs*.
223 */
224 if (waitpid(pid, &status, 0) == -1) {
225 perror("wait failed");
226 }
Peng Haitao02fa9302011-04-04 10:45:40 +0800227 if (WIFEXITED(status))
228 exit(WEXITSTATUS(status));
229 else
230 exit(status);
subrata_modak88af3352008-11-27 15:33:55 +0000231 }
232
233 /* To make all the containers share the same PGID as its parent */
234 setpgid(0, 0);
235
236 pid = getpid();
237 pgid = getpgid(pid);
238 ret = pipe(fd);
239 if (ret == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800240 tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
subrata_modak88af3352008-11-27 15:33:55 +0000241
Garrett Cooperad14e902010-12-16 10:03:44 -0800242 TEST(do_clone_unshare_test(T_CLONE, CLONE_NEWPID,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800243 create_nested_container, (void *)&count));
Garrett Cooperad14e902010-12-16 10:03:44 -0800244 if (TEST_RETURN == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800245 tst_brkm(TFAIL | TTERRNO, cleanup, "clone failed");
subrata_modak88af3352008-11-27 15:33:55 +0000246 }
247
248 close(fd[1]);
249 /* Waiting for the MAX_DEPTH number of containers to be created */
250 nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
251 close(fd[0]);
252 if (nbytes > 0)
253 tst_resm(TINFO, " %d %s", MAX_DEPTH, readbuffer);
Garrett Cooperad14e902010-12-16 10:03:44 -0800254 else
255 tst_brkm(TFAIL, cleanup, "unable to create %d containers",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256 MAX_DEPTH);
subrata_modak88af3352008-11-27 15:33:55 +0000257
Garrett Cooperad14e902010-12-16 10:03:44 -0800258 /* Kill the container created */
subrata_modak88af3352008-11-27 15:33:55 +0000259 kill_nested_containers();
subrata_modak88af3352008-11-27 15:33:55 +0000260 cleanup();
261
Garrett Cooper2c282152010-12-16 00:55:50 -0800262 tst_exit();
Peng Haitao02fa9302011-04-04 10:45:40 +0800263}