blob: d692259b3d20f9c04bf4d6a93cadec1192047f6a [file] [log] [blame]
subrata_modak069c67d2008-12-12 13:14:21 +00001/*
2* Copyright (c) Bull S.A.S. 2008
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_modak069c67d2008-12-12 13:14:21 +000014*
15***************************************************************************
16* File: pidns30.c
17*
18* Description:
19* This testcase checks if the si_pid is correctly set when a process
20* that has registered for notification on a posix mqueue is in a
21* descendant namespace wrt the process that sends a message to that posix
22* mqueue.
23*
24* Test Assertion & Strategy:
25* Parent Child
26* --------------------------------------------------------------------------
27* Create a POSIX mqueue.
28* Create a PID namespace container.
29* Open that mqueue for reading
30* Register for notification when a
31* message arrives in that mqueue
32* Install a handler for SIGUSR1.
33* Write something to the mqueue.
34* Inside the handler, check that
35* si_pid is set to 0
36*
37* Usage: <for command-line>
38* pidns30
39*
40* History:
41* DATE NAME DESCRIPTION
42* 01/12/08 Nadia Derbey Creation of this test.
43* <Nadia.Derbey@bull.net>
44*
45******************************************************************************/
46#define _GNU_SOURCE 1
47#include <sys/wait.h>
48#include <sys/types.h>
49#include <signal.h>
50#include <stdlib.h>
51#include <unistd.h>
52#include <stdio.h>
53#include <mqueue.h>
yaberauneya3e8f77b2009-11-14 23:58:26 +000054#include "test.h"
55#include "linux_syscall_numbers.h"
yaberauneyabe3fdcf2009-11-14 17:52:51 +000056#include "libclone.h"
Jan Stanceked991ae2014-07-29 10:50:27 +020057#include "pidns_helper.h"
subrata_modak069c67d2008-12-12 13:14:21 +000058
59char *TCID = "pidns30";
60int TST_TOTAL = 1;
61
Rishikesh K Rajak59367672010-04-29 19:00:01 +053062char *mqname = "mq1";
subrata_modak069c67d2008-12-12 13:14:21 +000063int result = TFAIL;
64
65int errno;
66int father_to_child[2];
67int child_to_father[2];
68
69#define CHILD_PID 1
70#define PARENT_PID 0
71
72#define MSG "HOW ARE YOU"
73#define MSG_PRIO 1
74
75#define NO_STEP -1
76#define F_STEP_0 0x00
77#define F_STEP_1 0x01
78#define F_STEP_2 0x02
79#define F_STEP_3 0x03
80#define C_STEP_0 0x10
81#define C_STEP_1 0x11
82#define C_STEP_2 0x12
83
Garrett Cooperad14e902010-12-16 10:03:44 -080084mqd_t rc = -1;
85mqd_t mqd = -1;
86
subrata_modak069c67d2008-12-12 13:14:21 +000087static void remove_pipe(int *fd)
88{
89 close(fd[0]);
90 close(fd[1]);
91}
92
93static void remove_mqueue(mqd_t mqd)
94{
yaberauneya3e8f77b2009-11-14 23:58:26 +000095 mq_close(mqd);
Jan Stancek359980f2013-02-15 10:16:05 +010096 ltp_syscall(__NR_mq_unlink, mqname);
subrata_modak069c67d2008-12-12 13:14:21 +000097}
98
Garrett Cooperad14e902010-12-16 10:03:44 -080099static void cleanup(void)
subrata_modak069c67d2008-12-12 13:14:21 +0000100{
Garrett Cooperad14e902010-12-16 10:03:44 -0800101 if (mqd != -1) {
subrata_modak069c67d2008-12-12 13:14:21 +0000102 remove_mqueue(mqd);
subrata_modak069c67d2008-12-12 13:14:21 +0000103 }
Garrett Cooperad14e902010-12-16 10:03:44 -0800104 if (rc != -1) {
105 remove_mqueue(rc);
106 }
107 remove_pipe(father_to_child);
108 remove_pipe(child_to_father);
subrata_modak069c67d2008-12-12 13:14:21 +0000109}
110
Garrett Cooperad14e902010-12-16 10:03:44 -0800111static void cleanup_child(void)
subrata_modak069c67d2008-12-12 13:14:21 +0000112{
Garrett Cooperad14e902010-12-16 10:03:44 -0800113 if (mqd != -1) {
Jan Stancek359980f2013-02-15 10:16:05 +0100114 ltp_syscall(__NR_mq_notify, mqd, NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800115 }
116 cleanup();
subrata_modak069c67d2008-12-12 13:14:21 +0000117}
118
119/*
120 * child_signal_handler() - to handle SIGUSR1
Garrett Cooperad14e902010-12-16 10:03:44 -0800121 *
122 * XXX (garrcoop): add calls to cleanup_child() -- or should this be handled
123 * from the libltp signal handler?
subrata_modak069c67d2008-12-12 13:14:21 +0000124 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800125static void child_signal_handler(int sig, siginfo_t * si, void *unused)
subrata_modak069c67d2008-12-12 13:14:21 +0000126{
127 char buf[256];
subrata_modak069c67d2008-12-12 13:14:21 +0000128 struct mq_attr attr;
129
130 if (si->si_signo != SIGUSR1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800131 printf("received signal = %d unexpectedly\n", si->si_signo);
subrata_modak069c67d2008-12-12 13:14:21 +0000132 return;
133 }
134
135 if (si->si_code != SI_MESGQ) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800136 printf("expected signal code SI_MESGQ; got %d instead\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800137 si->si_code);
subrata_modak069c67d2008-12-12 13:14:21 +0000138 return;
139 }
140
141 if (si->si_pid) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800142 printf("expected signal originator PID = 0; got %d instead\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 si->si_pid);
subrata_modak069c67d2008-12-12 13:14:21 +0000144 return;
Garrett Cooperad14e902010-12-16 10:03:44 -0800145 } else {
146 printf("signal originator PID = 0\n");
147 result = TPASS;
subrata_modak069c67d2008-12-12 13:14:21 +0000148 }
149
subrata_modak069c67d2008-12-12 13:14:21 +0000150 /*
151 * Now read the message - Be silent on errors since this is not the
152 * test purpose.
153 */
Garrett Coopere7a09402010-12-16 06:06:38 -0800154 rc = mq_getattr(si->si_int, &attr);
Garrett Cooperad14e902010-12-16 10:03:44 -0800155 if (rc != -1)
156 mq_receive(si->si_int, buf, attr.mq_msgsize, NULL);
subrata_modak069c67d2008-12-12 13:14:21 +0000157}
158
subrata_modak069c67d2008-12-12 13:14:21 +0000159/*
160 * child_fn() - Inside container
Garrett Cooperad14e902010-12-16 10:03:44 -0800161 *
162 * XXX (garrcoop): add more calls to cleanup_child()?
subrata_modak069c67d2008-12-12 13:14:21 +0000163 */
164int child_fn(void *arg)
165{
166 pid_t pid, ppid;
167 struct sigaction sa;
subrata_modak069c67d2008-12-12 13:14:21 +0000168 struct sigevent notif;
169 char buf[5];
170
171 /* Set process id and parent pid */
172 pid = getpid();
173 ppid = getppid();
174
175 if (pid != CHILD_PID || ppid != PARENT_PID) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800176 printf("pidns was not created\n");
177 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000178 }
179
180 /* Close the appropriate end of each pipe */
181 close(child_to_father[0]);
182 close(father_to_child[1]);
183
Garrett Cooperad14e902010-12-16 10:03:44 -0800184 while (read(father_to_child[0], buf, 1) != 1)
185 sleep(1);
186
Jan Stancek359980f2013-02-15 10:16:05 +0100187 mqd = ltp_syscall(__NR_mq_open, mqname, O_RDONLY, 0, NULL);
Garrett Coopere7a09402010-12-16 06:06:38 -0800188 if (mqd == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800189 perror("mq_open failed");
190 return 1;
191 } else
192 printf("mq_open succeeded\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000193
194 /* Register for notification on message arrival */
195 notif.sigev_notify = SIGEV_SIGNAL;
196 notif.sigev_signo = SIGUSR1;
197 notif.sigev_value.sival_int = mqd;
Jan Stancek359980f2013-02-15 10:16:05 +0100198 if (ltp_syscall(__NR_mq_notify, mqd, &notif) == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800199 perror("mq_notify failed");
200 return 1;
201 } else
202 printf("successfully registered for notification\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000203
204 /* Define handler for SIGUSR1 */
205 sa.sa_flags = SA_SIGINFO;
206 sigemptyset(&sa.sa_mask);
207 sa.sa_sigaction = child_signal_handler;
208 if (sigaction(SIGUSR1, &sa, NULL) == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800209 perror("sigaction failed");
210 return 1;
211 } else
212 printf("successfully registered handler for SIGUSR1\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000213
214 /* Ask parent to send a message to the mqueue */
215 if (write(child_to_father[1], "c:ok", 5) != 5) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800216 perror("write failed");
217 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000218 }
219
220 sleep(3);
221
222 /* Has parent sent a message? */
223 read(father_to_child[0], buf, 5);
Garrett Cooperad14e902010-12-16 10:03:44 -0800224 if (strcmp(buf, "f:ok") != 0) {
225 printf("parent did not send the message!\n");
226 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000227 }
Garrett Cooperad14e902010-12-16 10:03:44 -0800228 printf("parent is done - cleaning up\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000229
Garrett Cooperad14e902010-12-16 10:03:44 -0800230 cleanup_child();
subrata_modak069c67d2008-12-12 13:14:21 +0000231
232 exit(0);
233}
234
Jan Stanceked991ae2014-07-29 10:50:27 +0200235static void setup(void)
236{
237 tst_require_root(NULL);
238 check_newpid();
239}
240
subrata_modak069c67d2008-12-12 13:14:21 +0000241int main(int argc, char *argv[])
242{
subrata_modak069c67d2008-12-12 13:14:21 +0000243 int status;
244 char buf[5];
245 pid_t cpid;
subrata_modak069c67d2008-12-12 13:14:21 +0000246
Jan Stanceked991ae2014-07-29 10:50:27 +0200247 setup();
248
Garrett Cooperad14e902010-12-16 10:03:44 -0800249 if (pipe(child_to_father) == -1 || pipe(father_to_child) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800250 tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000251 }
252
Jan Stancek359980f2013-02-15 10:16:05 +0100253 ltp_syscall(__NR_mq_unlink, mqname);
subrata_modak069c67d2008-12-12 13:14:21 +0000254
255 /* container creation on PID namespace */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256 cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800257 if (cpid == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800259
Wanlong Gao354ebb42012-12-07 10:10:04 +0800260 mqd =
Jan Stancek359980f2013-02-15 10:16:05 +0100261 ltp_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800262 NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800263 if (mqd == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800264 tst_brkm(TBROK | TERRNO, cleanup, "mq_open failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800265 else
266 tst_resm(TINFO, "successfully created posix mqueue");
267
268 if (write(father_to_child[1], buf, 1) != 1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800269 tst_brkm(TBROK | TERRNO, cleanup, "write failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000270
271 /* Close the appropriate end of each pipe */
272 close(child_to_father[1]);
273 close(father_to_child[0]);
274
275 /* Is container ready */
276 read(child_to_father[0], buf, 5);
Garrett Cooperad14e902010-12-16 10:03:44 -0800277 if (strcmp(buf, "c:ok") != 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800278 tst_brkm(TBROK, cleanup,
279 "container did not respond as expected!");
subrata_modak069c67d2008-12-12 13:14:21 +0000280
yaberauneya3e8f77b2009-11-14 23:58:26 +0000281 rc = mq_send(mqd, MSG, strlen(MSG), MSG_PRIO);
Garrett Cooperad14e902010-12-16 10:03:44 -0800282 if (rc == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800283 tst_brkm(TBROK | TERRNO, cleanup, "mq_send failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800284 else
285 tst_resm(TINFO, "mq_send succeeded");
subrata_modak069c67d2008-12-12 13:14:21 +0000286
287 /* Tell the child the message has been sent */
Garrett Cooperad14e902010-12-16 10:03:44 -0800288 if (write(father_to_child[1], "f:ok", 5) != 5)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800289 tst_brkm(TBROK | TERRNO, cleanup, "write failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000290
291 /* Wait for child to finish */
Garrett Cooperad14e902010-12-16 10:03:44 -0800292 if (wait(&status) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800293 tst_resm(TBROK | TERRNO, "wait failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000294
Garrett Cooperad14e902010-12-16 10:03:44 -0800295 cleanup();
subrata_modak069c67d2008-12-12 13:14:21 +0000296
Garrett Cooper2c282152010-12-16 00:55:50 -0800297 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700298}