[PATCH 4/6][cr-tests]: eclone-4: Fail if clone_flags_high is non-zero

Sukadev Bhattiprolu sukadev at linux.vnet.ibm.com
Tue Feb 2 11:39:31 PST 2010


From: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
Date: Mon, 1 Feb 2010 18:10:32 -0800
Subject: [PATCH 4/6][cr-tests]: eclone-4: Fail if clone_flags_high is non-zero

To ensure future extendability, we want the unused fields to be 0. Ensure
eclone() fails if ->clone_flags_high field is non-0.

Signed-off-by: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
---
 eclone/Makefile   |    2 +-
 eclone/eclone-4.c |  116 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 1 deletions(-)
 create mode 100644 eclone/eclone-4.c

diff --git a/eclone/Makefile b/eclone/Makefile
index ebe508d..86ca859 100644
--- a/eclone/Makefile
+++ b/eclone/Makefile
@@ -3,7 +3,7 @@ CFLAGS = -Wall
 
 LDFLAGS = 
 
-PROGS = eclone-1 eclone-2 eclone-3
+PROGS = eclone-1 eclone-2 eclone-3 eclone-4
 
 all: $(PROGS)
 
diff --git a/eclone/eclone-4.c b/eclone/eclone-4.c
new file mode 100644
index 0000000..33a28ef
--- /dev/null
+++ b/eclone/eclone-4.c
@@ -0,0 +1,116 @@
+#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>
+#include "clone_args.h"
+
+/*
+ * Verify that eclone() fails if ->clone_flags_high is not 0.
+ */
+int verbose = 0;
+int child_tid, parent_tid;
+
+#define CHILD_TID1	377
+#define	CHILD_TID2	399
+#define	CHILD_ARG	(void *)0x979797
+
+pid_t pids_list[] = { CHILD_TID1, CHILD_TID2 };
+
+int do_child(void *arg)
+{
+	printf("FAIL: Child created with [%d, %d]. We expected eclone() to "
+			"fail with EINVAL since clone_flags_high is not 0\n",
+			 gettid(), getpid());
+	exit(2);
+}
+
+static int myclone(int (*child_fn)(void *), void *child_arg, 
+		unsigned int flags_low, int nr_pids, pid_t *pids_list)
+{
+	int rc;
+	void *stack;
+	struct clone_args ca;
+	int args_size;
+
+	stack = setup_stack(child_fn, child_arg, STACKSIZE);
+	if (!stack) {
+		printf("ERROR: setup_stack returns NULL for size %d\n",
+				STACKSIZE);
+		exit(1);
+	}
+
+	memset(&ca, 0, sizeof(ca));
+	ca.clone_flags_high = (u64)1 << 33;
+	ca.child_stack_base = (u64)(int)stack;
+	ca.child_stack_size = (u64)0;
+	ca.parent_tid_ptr = (u64)((int)&parent_tid);
+	ca.child_tid_ptr = (u64)((int)&child_tid);
+	ca.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, ca.parent_tid_ptr, ca.child_tid_ptr,
+				pids_list);
+	}
+
+	args_size = sizeof(struct clone_args);
+	rc = eclone(flags_low, &ca, args_size, pids_list);
+
+	if (verbose) {
+		printf("[%d, %d]: eclone() returned %d, error %d\n", getpid(),
+				gettid(), rc, errno);
+		fflush(stdout);
+	}
+
+	if (rc < 0 && errno == EINVAL) {
+		printf("PASS: eclone() failed (clone_flags_high not 0)\n");
+		exit(0);
+	} else {
+		printf("FAIL: Expected eclone() to fail with EINVAL");
+		exit(1);
+	}
+
+	return rc;
+}
+
+int main()
+{
+	int rc, pid, status;
+	unsigned long flags; 
+	int nr_pids = 1;
+
+	flags = SIGCHLD|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID;
+	flags = SIGCHLD;
+
+	pid = myclone(do_child, (void *)CHILD_ARG, flags, nr_pids, pids_list);
+
+	if (verbose) {
+		printf("[%d, %d]: Parent waiting for %d\n", getpid(),
+					gettid(), pid);
+	}
+
+	rc = waitpid(pid, &status, __WALL);
+	if (rc < 0) {
+		printf("ERROR: ");
+		verbose = 1;
+	}
+
+	if (verbose) {
+		printf("\twaitpid(): child %d, rc %d, error %d, status 0x%x\n",
+				getpid(), rc, errno, status);
+		if (rc >=0) {
+			if (WIFEXITED(status)) {
+				printf("\t EXITED, %d\n", WEXITSTATUS(status));
+			} else if (WIFSIGNALED(status)) {
+				printf("\t SIGNALED, %d\n", WTERMSIG(status));
+			} 
+		}
+	}
+	return 0;
+}
-- 
1.6.6.1



More information about the Containers mailing list