From: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
To: serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org
Cc: Containers
<containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>
Subject: [PATCH 5/6][cr-test][v2]: eclone-5: nr_pids must not exceed nesting level
Date: Tue, 9 Feb 2010 11:36:19 -0800 [thread overview]
Message-ID: <20100209193619.GD32274@us.ibm.com> (raw)
In-Reply-To: <20100209193331.GB30005-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
From: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Date: Mon, 1 Feb 2010 18:13:51 -0800
Subject: [PATCH 5/6] eclone-5: nr_pids must not exceed nesting level
Verify that eclone() fails if nr_pids exceeds the current nesting level
of pid namespaces. Also verify that eclone() succeeds in choosing a pid
for a process in a descendant pid namespace.
Changelog[v2]:
- Use libeclone.a from user-cr git tree so tests are portable across
architectures.
- Fix some nits identified by Serge Hallyn
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
eclone/Makefile | 2 +-
eclone/eclone-5.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+), 1 deletions(-)
create mode 100644 eclone/eclone-5.c
diff --git a/eclone/Makefile b/eclone/Makefile
index ba3d6ac..7bd5585 100644
--- a/eclone/Makefile
+++ b/eclone/Makefile
@@ -10,7 +10,7 @@ LDFLAGS =
LIB_ECLONE = $(USER_CR_DIR)/libeclone.a
-PROGS = eclone-1 eclone-2 eclone-3 eclone-4
+PROGS = eclone-1 eclone-2 eclone-3 eclone-4 eclone-5
all: $(PROGS)
diff --git a/eclone/eclone-5.c b/eclone/eclone-5.c
new file mode 100644
index 0000000..2d36898
--- /dev/null
+++ b/eclone/eclone-5.c
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+#define _GNU_SOURCE
+#include <sched.h>
+#include "eclone-tests.h"
+#include "genstack.h"
+
+/*
+ * Verify that eclone() fails if nr_pids exceeds the current nesting level
+ * of pid namespaces
+ */
+int verbose = 0;
+
+#define CHILD_TID1 377
+#define CHILD_TID2 399
+#define CHILD_ARG (void *)0x979797
+
+pid_t pids[] = { CHILD_TID1, CHILD_TID2 };
+int parent_tid;
+int child_tid;
+
+int do_child(void *arg)
+{
+ if (verbose)
+ printf("Child created with [%d, %d]\n", gettid(), getpid());
+
+ sleep(2);
+ exit(0);
+}
+
+static int do_eclone(int (*child_fn)(void *), void *child_arg,
+ unsigned int flags_low, int nr_pids, pid_t *pids)
+{
+ int rc;
+ void *stack;
+ struct clone_args clone_args;
+ int args_size;
+
+ stack = genstack_alloc(STACKSIZE);
+ if (!stack) {
+ printf("ERROR: setup_stack returns NULL for size %d\n",
+ STACKSIZE);
+ exit(1);
+ }
+
+ memset(&clone_args, 0, sizeof(clone_args));
+ clone_args.child_stack = (u64)(int)genstack_sp(stack);
+ clone_args.child_stack_size = (u64)0;
+ clone_args.parent_tid_ptr = (u64)((int)&parent_tid);
+ clone_args.child_tid_ptr = (u64)((int)&child_tid);
+ clone_args.nr_pids = nr_pids;
+
+ if (verbose) {
+ printf("[%d, %d]: Parent:\n\t child_stack 0x%p, ptidp %llx, "
+ "ctidp %llx, pids %p\n", getpid(), gettid(),
+ stack, clone_args.parent_tid_ptr,
+ clone_args.child_tid_ptr, pids);
+ }
+
+ errno = 0;
+ args_size = sizeof(struct clone_args);
+ rc = eclone(child_fn, child_arg, flags_low, &clone_args, pids);
+
+ if (verbose) {
+ printf("[%d, %d]: eclone() returned %d, error %d\n", getpid(),
+ gettid(), rc, errno);
+ fflush(stdout);
+ }
+
+ return rc;
+}
+
+int do_test(void *arg)
+{
+ int rc, pid, status;
+ unsigned long flags;
+ int nested_ns;
+ int nr_pids;
+ int error;
+
+ nested_ns = *(int *)arg;
+ nr_pids = 2;
+
+ flags = SIGCHLD|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID;
+
+ pid = do_eclone(do_child, CHILD_ARG, flags, nr_pids, pids);
+
+ error = 0;
+ if (pid < 0)
+ error = errno;
+
+ /* If we did create a child, wait for it to exit */
+ if (pid > 0) {
+ rc = waitpid(pid, &status, __WALL);
+ if (rc < 0) {
+ printf("%d: ERROR: waitpid() rc %d, error %d\n",
+ getpid(), rc, errno);
+ verbose = 1;
+ }
+ }
+
+ if (verbose) {
+ printf("%d: nested_ns %d, pid %d, error %d\n", getpid(),
+ nested_ns, pid, error);
+ }
+
+ /*
+ * We set nr_pids to 2 above. If we cloned from current pid ns,
+ * eclone() must fail with EINVAL. If we eclone() from a nested pid
+ * ns, eclone() must succeed. In all other cases, test has failed.
+ */
+ rc = 0;
+ if (!nested_ns && (pid < 0) && (error == EINVAL)) {
+ printf("%d: PASSED: Got EINVAL when nr_pids > nesting-depth\n",
+ getpid());
+ } else if (nested_ns && (pid > 0)) {
+ printf("%d: PASSED: eclone() succeeded in nested pid-ns, "
+ "pid %d\n", getpid(), pid);
+ } else {
+ printf("%d: FAILED: nested_ns %d, pid %d, error %d\n", getpid(),
+ nested_ns, pid, error);
+ rc = 1;
+ }
+
+ fflush(stdout);
+ return rc;
+}
+
+int main()
+{
+ int rc, pid, status;
+ int nested_ns;
+ unsigned long flags;
+ void *stack;
+
+ /* First test in current pid namespace */
+ nested_ns = 0;
+ rc = do_test(&nested_ns);
+ if (rc)
+ exit(rc);
+
+ /* Then test in a nested pid-namespace - use normal clone() */
+ stack = malloc(STACKSIZE);
+ if (!stack) {
+ printf("ERROR: setup_stack returns NULL for size %d\n",
+ STACKSIZE);
+ exit(1);
+ }
+ stack += (STACKSIZE - 1);
+
+ nested_ns = 1;
+ flags = SIGCHLD|CLONE_NEWPID|CLONE_NEWNS;
+ pid = clone(do_test, stack, flags, (void *)&nested_ns, NULL, NULL, NULL);
+ if (pid < 0) {
+ printf("ERROR: clone() failed, pid %d, error %s\n", pid,
+ strerror(errno));
+ exit(1);
+ }
+
+ rc = waitpid(pid, &status, __WALL);
+ if (rc < 0) {
+ printf("ERROR: waitpid() failed, rc %d, error %s\n", rc,
+ strerror(errno));
+ fflush(stdout);
+ exit(1);
+ }
+ return 0;
+}
--
1.6.6.1
next prev parent reply other threads:[~2010-02-09 19:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-09 19:33 [PATCH 1/6][cr-test][v2]: eclone-1: Test basic functionality Sukadev Bhattiprolu
[not found] ` <20100209193331.GB30005-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2010-02-09 19:34 ` [PATCH 2/6][cr-test][v2]: eclone-2: Ensure eclone() fails if selected pid is in use Sukadev Bhattiprolu
2010-02-09 19:35 ` [PATCH 3/6][cr-test][v2]: Verify eclone() fails if reserved fields are not 0 Sukadev Bhattiprolu
2010-02-09 19:35 ` [PATCH 4/6][cr-test][v2]: Verify eclone() fails if clone_flags_high is non-zero Sukadev Bhattiprolu
2010-02-09 19:36 ` Sukadev Bhattiprolu [this message]
[not found] ` <20100209193619.GD32274-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2010-02-09 21:17 ` [PATCH 5/6][cr-test][v2]: eclone-5: nr_pids must not exceed nesting level Serge E. Hallyn
[not found] ` <20100209211705.GA32631-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2010-02-10 1:28 ` Sukadev Bhattiprolu
[not found] ` <20100210012831.GA20795-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2010-02-10 15:47 ` Serge E. Hallyn
2010-02-09 19:37 ` [PATCH 6/6][cr-test][v2]: eclone/runtests.sh: Wrapper script for eclone tests Sukadev Bhattiprolu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100209193619.GD32274@us.ibm.com \
--to=sukadev-23vcf4htsmix0ybbhkvfkdbpr1lh4cv8@public.gmane.org \
--cc=containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.