This testcase checks if the si_pid is correctly set when a process
that has registered for notification on a posix mqueue is in an
ancestor namespace wrt the process that sends a message to that posix
mqueue.

Signed-off-by: Nadia Derbey <[EMAIL PROTECTED]>
---
 testcases/kernel/containers/pidns/Makefile  |    2 
 testcases/kernel/containers/pidns/pidns05.c |  304 ++++++++++++++++++++++++++++
 2 files changed, 305 insertions(+), 1 deletion(-)

Index: ltp-full-20080831/testcases/kernel/containers/pidns/pidns05.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ ltp-full-20080831/testcases/kernel/containers/pidns/pidns05.c       
2008-12-04 17:38:15.000000000 +0100
@@ -0,0 +1,304 @@
+/*
+* Copyright (c) Bull S.A.S. 2008
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+* the GNU General Public License for more details.
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+***************************************************************************
+* File: pidns05.c
+*
+*   Description:
+*    This testcase checks if the si_pid is correctly set when a process
+*    that has registered for notification on a posix mqueue is in an
+*    ancestor namespace wrt the process that sends a message to that posix
+*    mqueue.
+*
+*   Test Assertion & Strategy:
+*    Parent                                   Child
+*    --------------------------------------------------------------------------
+*    Create a POSIX mqueue.
+*    Create a PID namespace container.
+*    Register for notification when a
+*       message arrives in that mqueue
+*    Install a handler for SIGUSR1.
+*                                             Open that mqueue for writing
+*                                             Write something to the mqueue.
+*    Inside the handler, check that
+*       si_pid is set to the child's pid
+*
+*   Usage: <for command-line>
+*    pidns05
+*
+*   History:
+*    DATE      NAME                             DESCRIPTION
+*    04/12/08  Nadia Derbey               Creation of this test.
+*              <[EMAIL PROTECTED]>
+*
+******************************************************************************/
+#define _GNU_SOURCE 1
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <mqueue.h>
+#include <usctest.h>
+#include <test.h>
+#include <libclone.h>
+
+char *TCID = "pidns05";
+int TST_TOTAL = 1;
+
+char *mqname = "/mq1";
+int result = TFAIL;
+
+int errno;
+int father_to_child[2];
+
+#define CHILD_PID       1
+#define PARENT_PID      0
+
+#define MSG      "HOW ARE YOU"
+#define MSG_PRIO 1
+
+struct notify_info {
+       mqd_t mqd;
+       pid_t pid;
+};
+
+/*
+ * cleanup() - performs all ONE TIME cleanup for this test at
+ *             completion or premature exit.
+ */
+static void cleanup(int r)
+{
+    /* Clean the test testcase as LTP wants*/
+    TEST_CLEANUP;
+
+    /* exit with return code appropriate for results */
+    tst_exit(r);
+}
+
+/*
+ * child_fn() - Inside container
+ */
+int child_fn(void *arg)
+{
+       pid_t pid, ppid;
+       mqd_t mqd;
+       char buf[5];
+
+       /* Set process id and parent pid */
+       pid = getpid();
+       ppid = getppid();
+
+       if (pid != CHILD_PID || ppid != PARENT_PID) {
+               tst_resm(TBROK, "cinit: pidns is not created");
+               cleanup(TBROK);
+       }
+
+       /* Close the appropriate end of pipe */
+       close(father_to_child[1]);
+
+       /* Is parent ready to receive a message? */
+       read(father_to_child[0], buf, 5);
+       if (strcmp(buf, "f:ok")) {
+               tst_resm(TBROK, "cinit: parent did not send the message!");
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "cinit: my father is ready to receive a message");
+
+       mqd = mq_open(mqname, O_WRONLY);
+       if (mqd == (mqd_t)-1) {
+               tst_resm(TBROK, "cinit: mq_open() failed (%s)",
+                       strerror(errno));
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "cinit: mq_open succeeded");
+
+       if (mq_send(mqd, MSG, strlen(MSG), MSG_PRIO) == (mqd_t)-1) {
+               tst_resm(TBROK, "cinit: mq_send() failed (%s)",
+                       strerror(errno));
+               mq_close(mqd);
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "cinit: mq_send() succeeded");
+
+       /* Cleanup and exit */
+       mq_close(mqd);
+       close(father_to_child[0]);
+       exit(0);
+}
+
+static void remove_pipe(int *fd)
+{
+       close(fd[0]);
+       close(fd[1]);
+}
+
+/*
+ * father_signal_handler()
+ */
+static void father_signal_handler(int sig, siginfo_t *si, void *unused)
+{
+       char buf[256];
+       struct mq_attr attr;
+       struct notify_info *info;
+
+       if (si->si_signo != SIGUSR1) {
+               tst_resm(TBROK, "father: received %s unexpectedly",
+                       strsignal(si->si_signo));
+               return;
+       }
+
+       if (si->si_code != SI_MESGQ) {
+               tst_resm(TBROK, "father: expected signal code SI_MESGQ - "
+                       "Got %d", si->si_code);
+               return;
+       }
+
+       if (!si->si_ptr) {
+               tst_resm(TBROK, "father: expected si_ptr - Got NULL");
+               return;
+       }
+
+       info = (struct notify_info *)si->si_ptr;
+
+       if (si->si_pid != info->pid) {
+               tst_resm(TFAIL,
+                       "father: expected signal originator PID = %d - Got %d",
+                       info->pid, si->si_pid);
+               return;
+       }
+
+       tst_resm(TPASS, "father: signal originator PID = %d", si->si_pid);
+       result = TPASS;
+
+       /*
+        * Now read the message - Be silent on errors since this is not the
+        * test purpose.
+        */
+       if (!mq_getattr(info->mqd, &attr))
+               mq_receive(info->mqd, buf, attr.mq_msgsize, NULL);
+}
+
+/***********************************************************************
+*   M A I N
+***********************************************************************/
+
+int main(int argc, char *argv[])
+{
+       int stack_size = getpagesize() * 4;
+       void *stack = malloc(stack_size);
+       void *childstack;
+       pid_t cpid;
+       mqd_t mqd;
+       struct sigevent notif;
+       struct sigaction sa;
+       int status;
+       struct notify_info info;
+
+       if (!stack) {
+               tst_resm(TBROK, "parent: stack creation failed.");
+               cleanup(TBROK);
+       }
+
+       if (pipe(father_to_child) == -1) {
+               tst_resm(TBROK, "parent: pipe() failed. aborting!");
+               cleanup(TBROK);
+       }
+
+       mq_unlink(mqname);
+       mqd = mq_open(mqname, O_RDWR|O_CREAT|O_EXCL, 0777, NULL);
+       if (mqd == (mqd_t)-1) {
+               tst_resm(TBROK, "parent: mq_open() failed (%s)",
+                       strerror(errno));
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "parent: successfully created posix mqueue");
+
+       /* container creation on PID namespace */
+       childstack = stack + stack_size;
+       cpid = clone(child_fn, childstack, CLONE_NEWPID|SIGCHLD, NULL);
+       if (cpid < 0) {
+               tst_resm(TBROK, "parent: clone() failed(%s)", strerror(errno));
+               mq_close(mqd);
+               mq_unlink(mqname);
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "parent: successfully created child (pid = %d)", cpid);
+
+       /* Register for notification on message arrival */
+       notif.sigev_notify = SIGEV_SIGNAL;
+       notif.sigev_signo = SIGUSR1;
+       info.mqd = mqd;
+       info.pid = cpid;
+       notif.sigev_value.sival_ptr = &info;
+       if (mq_notify(mqd, &notif) == (mqd_t)-1) {
+               tst_resm(TBROK, "parent: mq_notify() failed (%s)",
+                       strerror(errno));
+               mq_close(mqd);
+               mq_unlink(mqname);
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "parent: successfully registered for notification");
+
+       /* Define handler for SIGUSR1 */
+       sa.sa_flags = SA_SIGINFO;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_sigaction = father_signal_handler;
+       if (sigaction(SIGUSR1, &sa, NULL) == -1) {
+               tst_resm(TBROK, "parent: sigaction() failed(%s)",
+                       strerror(errno));
+               mq_notify(mqd, NULL);
+               mq_close(mqd);
+               mq_unlink(mqname);
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+       tst_resm(TINFO, "parent: successfully registered handler for SIGUSR1");
+
+       /* Close the appropriate end of pipe */
+       close(father_to_child[0]);
+
+       /* Tell the child a message can be sent */
+       if (write(father_to_child[1], "f:ok", 5) != 5) {
+               tst_resm(TBROK, "parent: pipe is broken(%s)", strerror(errno));
+               mq_notify(mqd, NULL);
+               mq_close(mqd);
+               mq_unlink(mqname);
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+
+       sleep(3);
+
+       /* Wait for child to finish */
+       if (wait(&status) == -1) {
+               tst_resm(TBROK, "parent: wait() failed(%s)", strerror(errno));
+               mq_close(mqd);
+               mq_unlink(mqname);
+               remove_pipe(father_to_child);
+               cleanup(TBROK);
+       }
+
+       mq_close(mqd);
+       mq_unlink(mqname);
+       close(father_to_child[1]);
+       cleanup(result);
+
+       /* NOT REACHED */
+       return 0;
+}    /* End main */
Index: ltp-full-20080831/testcases/kernel/containers/pidns/Makefile
===================================================================
--- ltp-full-20080831.orig/testcases/kernel/containers/pidns/Makefile   
2008-12-04 13:44:31.000000000 +0100
+++ ltp-full-20080831/testcases/kernel/containers/pidns/Makefile        
2008-12-04 16:23:33.000000000 +0100
@@ -23,7 +23,7 @@ CPPFLAGS += -I../../../../include -I../l
 LDLIBS += -L../../../../lib -L../libclone ../libclone/libclone.a -lltp -lrt
 
 SRCS    = $(wildcard *.c)
-NOLTPSRCS = pidns01.c pidns02.c pidns03.c pidns04.c
+NOLTPSRCS = pidns01.c pidns02.c pidns03.c pidns04.c pidns05.c
 TARGETS = $(patsubst %.c,%,$(SRCS))
 NOLTP_TARGETS = $(patsubst %.c,%_noltp,$(NOLTPSRCS))
 

-- 

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to