blob: b29e6b7a12d4a48b2d23722cb0455763f551b7ba [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 "usctest.h"
55#include "test.h"
56#include "linux_syscall_numbers.h"
yaberauneyabe3fdcf2009-11-14 17:52:51 +000057#include "libclone.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);
109
110 TEST_CLEANUP;
subrata_modak069c67d2008-12-12 13:14:21 +0000111}
112
Garrett Cooperad14e902010-12-16 10:03:44 -0800113static void cleanup_child(void)
subrata_modak069c67d2008-12-12 13:14:21 +0000114{
Garrett Cooperad14e902010-12-16 10:03:44 -0800115 if (mqd != -1) {
Jan Stancek359980f2013-02-15 10:16:05 +0100116 ltp_syscall(__NR_mq_notify, mqd, NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800117 }
118 cleanup();
subrata_modak069c67d2008-12-12 13:14:21 +0000119}
120
121/*
122 * child_signal_handler() - to handle SIGUSR1
Garrett Cooperad14e902010-12-16 10:03:44 -0800123 *
124 * XXX (garrcoop): add calls to cleanup_child() -- or should this be handled
125 * from the libltp signal handler?
subrata_modak069c67d2008-12-12 13:14:21 +0000126 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800127static void child_signal_handler(int sig, siginfo_t * si, void *unused)
subrata_modak069c67d2008-12-12 13:14:21 +0000128{
129 char buf[256];
subrata_modak069c67d2008-12-12 13:14:21 +0000130 struct mq_attr attr;
131
132 if (si->si_signo != SIGUSR1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800133 printf("received signal = %d unexpectedly\n", si->si_signo);
subrata_modak069c67d2008-12-12 13:14:21 +0000134 return;
135 }
136
137 if (si->si_code != SI_MESGQ) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800138 printf("expected signal code SI_MESGQ; got %d instead\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 si->si_code);
subrata_modak069c67d2008-12-12 13:14:21 +0000140 return;
141 }
142
143 if (si->si_pid) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800144 printf("expected signal originator PID = 0; got %d instead\n",
Wanlong Gao354ebb42012-12-07 10:10:04 +0800145 si->si_pid);
subrata_modak069c67d2008-12-12 13:14:21 +0000146 return;
Garrett Cooperad14e902010-12-16 10:03:44 -0800147 } else {
148 printf("signal originator PID = 0\n");
149 result = TPASS;
subrata_modak069c67d2008-12-12 13:14:21 +0000150 }
151
subrata_modak069c67d2008-12-12 13:14:21 +0000152 /*
153 * Now read the message - Be silent on errors since this is not the
154 * test purpose.
155 */
Garrett Coopere7a09402010-12-16 06:06:38 -0800156 rc = mq_getattr(si->si_int, &attr);
Garrett Cooperad14e902010-12-16 10:03:44 -0800157 if (rc != -1)
158 mq_receive(si->si_int, buf, attr.mq_msgsize, NULL);
subrata_modak069c67d2008-12-12 13:14:21 +0000159}
160
subrata_modak069c67d2008-12-12 13:14:21 +0000161/*
162 * child_fn() - Inside container
Garrett Cooperad14e902010-12-16 10:03:44 -0800163 *
164 * XXX (garrcoop): add more calls to cleanup_child()?
subrata_modak069c67d2008-12-12 13:14:21 +0000165 */
166int child_fn(void *arg)
167{
168 pid_t pid, ppid;
169 struct sigaction sa;
subrata_modak069c67d2008-12-12 13:14:21 +0000170 struct sigevent notif;
171 char buf[5];
172
173 /* Set process id and parent pid */
174 pid = getpid();
175 ppid = getppid();
176
177 if (pid != CHILD_PID || ppid != PARENT_PID) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800178 printf("pidns was not created\n");
179 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000180 }
181
182 /* Close the appropriate end of each pipe */
183 close(child_to_father[0]);
184 close(father_to_child[1]);
185
Garrett Cooperad14e902010-12-16 10:03:44 -0800186 while (read(father_to_child[0], buf, 1) != 1)
187 sleep(1);
188
Jan Stancek359980f2013-02-15 10:16:05 +0100189 mqd = ltp_syscall(__NR_mq_open, mqname, O_RDONLY, 0, NULL);
Garrett Coopere7a09402010-12-16 06:06:38 -0800190 if (mqd == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800191 perror("mq_open failed");
192 return 1;
193 } else
194 printf("mq_open succeeded\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000195
196 /* Register for notification on message arrival */
197 notif.sigev_notify = SIGEV_SIGNAL;
198 notif.sigev_signo = SIGUSR1;
199 notif.sigev_value.sival_int = mqd;
Jan Stancek359980f2013-02-15 10:16:05 +0100200 if (ltp_syscall(__NR_mq_notify, mqd, &notif) == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800201 perror("mq_notify failed");
202 return 1;
203 } else
204 printf("successfully registered for notification\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000205
206 /* Define handler for SIGUSR1 */
207 sa.sa_flags = SA_SIGINFO;
208 sigemptyset(&sa.sa_mask);
209 sa.sa_sigaction = child_signal_handler;
210 if (sigaction(SIGUSR1, &sa, NULL) == -1) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800211 perror("sigaction failed");
212 return 1;
213 } else
214 printf("successfully registered handler for SIGUSR1\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000215
216 /* Ask parent to send a message to the mqueue */
217 if (write(child_to_father[1], "c:ok", 5) != 5) {
Garrett Cooperad14e902010-12-16 10:03:44 -0800218 perror("write failed");
219 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000220 }
221
222 sleep(3);
223
224 /* Has parent sent a message? */
225 read(father_to_child[0], buf, 5);
Garrett Cooperad14e902010-12-16 10:03:44 -0800226 if (strcmp(buf, "f:ok") != 0) {
227 printf("parent did not send the message!\n");
228 return 1;
subrata_modak069c67d2008-12-12 13:14:21 +0000229 }
Garrett Cooperad14e902010-12-16 10:03:44 -0800230 printf("parent is done - cleaning up\n");
subrata_modak069c67d2008-12-12 13:14:21 +0000231
Garrett Cooperad14e902010-12-16 10:03:44 -0800232 cleanup_child();
subrata_modak069c67d2008-12-12 13:14:21 +0000233
234 exit(0);
235}
236
subrata_modak069c67d2008-12-12 13:14:21 +0000237int main(int argc, char *argv[])
238{
subrata_modak069c67d2008-12-12 13:14:21 +0000239 int status;
240 char buf[5];
241 pid_t cpid;
subrata_modak069c67d2008-12-12 13:14:21 +0000242
Garrett Cooperad14e902010-12-16 10:03:44 -0800243 if (pipe(child_to_father) == -1 || pipe(father_to_child) == -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800244 tst_brkm(TBROK | TERRNO, cleanup, "pipe failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000245 }
246
Jan Stancek359980f2013-02-15 10:16:05 +0100247 ltp_syscall(__NR_mq_unlink, mqname);
subrata_modak069c67d2008-12-12 13:14:21 +0000248
249 /* container creation on PID namespace */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800250 cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800251 if (cpid == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800252 tst_brkm(TBROK | TERRNO, cleanup, "clone failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800253
Wanlong Gao354ebb42012-12-07 10:10:04 +0800254 mqd =
Jan Stancek359980f2013-02-15 10:16:05 +0100255 ltp_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256 NULL);
Garrett Cooperad14e902010-12-16 10:03:44 -0800257 if (mqd == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800258 tst_brkm(TBROK | TERRNO, cleanup, "mq_open failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800259 else
260 tst_resm(TINFO, "successfully created posix mqueue");
261
262 if (write(father_to_child[1], buf, 1) != 1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800263 tst_brkm(TBROK | TERRNO, cleanup, "write failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000264
265 /* Close the appropriate end of each pipe */
266 close(child_to_father[1]);
267 close(father_to_child[0]);
268
269 /* Is container ready */
270 read(child_to_father[0], buf, 5);
Garrett Cooperad14e902010-12-16 10:03:44 -0800271 if (strcmp(buf, "c:ok") != 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800272 tst_brkm(TBROK, cleanup,
273 "container did not respond as expected!");
subrata_modak069c67d2008-12-12 13:14:21 +0000274
yaberauneya3e8f77b2009-11-14 23:58:26 +0000275 rc = mq_send(mqd, MSG, strlen(MSG), MSG_PRIO);
Garrett Cooperad14e902010-12-16 10:03:44 -0800276 if (rc == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 tst_brkm(TBROK | TERRNO, cleanup, "mq_send failed");
Garrett Cooperad14e902010-12-16 10:03:44 -0800278 else
279 tst_resm(TINFO, "mq_send succeeded");
subrata_modak069c67d2008-12-12 13:14:21 +0000280
281 /* Tell the child the message has been sent */
Garrett Cooperad14e902010-12-16 10:03:44 -0800282 if (write(father_to_child[1], "f:ok", 5) != 5)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800283 tst_brkm(TBROK | TERRNO, cleanup, "write failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000284
285 /* Wait for child to finish */
Garrett Cooperad14e902010-12-16 10:03:44 -0800286 if (wait(&status) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800287 tst_resm(TBROK | TERRNO, "wait failed");
subrata_modak069c67d2008-12-12 13:14:21 +0000288
Garrett Cooperad14e902010-12-16 10:03:44 -0800289 cleanup();
subrata_modak069c67d2008-12-12 13:14:21 +0000290
Garrett Cooper2c282152010-12-16 00:55:50 -0800291 tst_exit();
Chris Dearmanec6edca2012-10-17 19:54:01 -0700292}