* [PATCH 1/9] user-cr: add eclone/clone_args header
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 2/9] user-cr: x86_32 eclone wrapper Nathan Lynch
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Declare these interfaces which will replace clone_with_pids.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
eclone.h | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
create mode 100644 eclone.h
diff --git a/eclone.h b/eclone.h
new file mode 100644
index 0000000..601a621
--- /dev/null
+++ b/eclone.h
@@ -0,0 +1,25 @@
+#ifndef _ECLONE_H_
+#define _ECLONE_H_
+
+#include <stdint.h>
+
+struct clone_args {
+ uint64_t clone_flags_high;
+ uint64_t child_stack;
+ uint64_t child_stack_size;
+ uint64_t parent_tid_ptr;
+ uint64_t child_tid_ptr;
+
+ uint32_t nr_pids;
+
+ uint32_t reserved0;
+ uint64_t reserved1;
+};
+
+/* arch-dependent code implements this interface */
+extern int eclone(int (*fn)(void *), void *fn_arg,
+ int clone_flags_low,
+ struct clone_args *clone_args,
+ pid_t *pids);
+
+#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 2/9] user-cr: x86_32 eclone wrapper
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-11-18 0:55 ` [PATCH 1/9] user-cr: add eclone/clone_args header Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 3/9] user-cr: s390 " Nathan Lynch
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
---
clone_x86_32.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/clone_x86_32.c b/clone_x86_32.c
index 8ab3c3e..61b593c 100644
--- a/clone_x86_32.c
+++ b/clone_x86_32.c
@@ -81,3 +81,68 @@ int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
}
#endif
+
+#include "eclone.h"
+
+#ifndef __NR_eclone
+#define __NR_eclone 337
+#endif
+
+int eclone(int (*fn)(void *), void *fn_arg, int clone_flags_low,
+ struct clone_args *clone_args, pid_t *pids)
+{
+ struct clone_args my_args;
+ long retval;
+ void **newstack;
+
+ if (clone_args->child_stack) {
+ /*
+ * Set up the stack for child:
+ * - fn_arg will be the argument for the child function
+ * - the fn pointer will be loaded into ebx after the clone
+ */
+ newstack = (void **)(unsigned long)(clone_args->child_stack +
+ clone_args->child_stack_size);
+ *--newstack = fn_arg;
+ *--newstack = fn;
+ } else
+ newstack = (void **)0;
+
+ my_args = *clone_args;
+ my_args.child_stack = (unsigned long)newstack;
+ my_args.child_stack_size = 0;
+
+ __asm__ __volatile__(
+ "movl %0, %%ebx\n\t" /* flags -> 1st (ebx) */
+ "movl %1, %%ecx\n\t" /* clone_args -> 2nd (ecx) */
+ "movl %2, %%edx\n\t" /* args_size -> 3rd (edx) */
+ "movl %3, %%edi\n\t" /* pids -> 4th (edi) */
+ "pushl %%ebp\n\t" /* save value of ebp */
+ :
+ :"b" (clone_flags_low),
+ "c" (&my_args),
+ "d" (sizeof(my_args)),
+ "D" (pids)
+ );
+
+ __asm__ __volatile__(
+ "int $0x80\n\t" /* Linux/i386 system call */
+ "testl %0,%0\n\t" /* check return value */
+ "jne 1f\n\t" /* jump if parent */
+ "popl %%ebx\n\t" /* get subthread function */
+ "call *%%ebx\n\t" /* start subthread function */
+ "movl %2,%0\n\t"
+ "int $0x80\n" /* exit system call: exit subthread */
+ "1:\n\t"
+ "popl %%ebp\t" /* restore parent's ebp */
+ :"=a" (retval)
+ :"0" (__NR_eclone), "i" (__NR_exit)
+ :"ebx", "ecx"
+ );
+
+ if (retval < 0) {
+ errno = -retval;
+ retval = -1;
+ }
+ return retval;
+}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 3/9] user-cr: s390 eclone wrapper
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-11-18 0:55 ` [PATCH 1/9] user-cr: add eclone/clone_args header Nathan Lynch
2009-11-18 0:55 ` [PATCH 2/9] user-cr: x86_32 eclone wrapper Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
[not found] ` <1258505746-31182-4-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-11-18 0:55 ` [PATCH 4/9] user-cr: ppc32 " Nathan Lynch
` (6 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Based on original work from Serge Hallyn.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
clone_s390x.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/clone_s390x.c b/clone_s390x.c
index dada822..5ed6f15 100644
--- a/clone_s390x.c
+++ b/clone_s390x.c
@@ -70,3 +70,65 @@ int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
}
#endif /* !defined(__NR_clone_with_pids) */
+
+#include "eclone.h"
+
+#ifndef __NR_eclone
+#define __NR_eclone 332
+#endif
+
+typedef unsigned long long u64;
+
+#define do_eclone(flags, pids, args, sz) \
+( { \
+ register unsigned long int __r1 asm ("1") = (unsigned long int)(__NR_eclone);
+ register unsigned long int __r2 asm ("2") = (unsigned long int)(flags); \
+ register unsigned long int __r3 asm ("3") = (unsigned long int)(args); \
+ register unsigned long int __r4 asm ("4") = (unsigned long int)(sz); \
+ register unsigned long int __r5 asm ("5") = (unsigned long int)(pids); \
+ register long int __result asm ("2"); \
+ __asm__ __volatile__( \
+ " svc 0\n" /* do __NR_eclone syscall */ \
+ " ltgr %%r2,%%r2\n" /* returned 0? */ \
+ " jnz 1f\n" /* if not goto label 1 */ \
+ " lg %%r3,0(%%r15)\n" /* get fnarg off stack into arg 1 */ \
+ " lg %%r2,8(%%r15)\n" /* get fn off stack int r3 basr*/ \
+ " lgr %%r1,%%r15\n" /* tmp store old stack pointer */ \
+ " aghi %%r15,-160\n" /* move the stack */ \
+ " stg %%r1,0(%%r15)\n" /* and save old stack pointer */ \
+ " basr %%r14,%%r3\n" /* call fn(arg) */ \
+ " svc 1\n" /* call exit */ \
+ " 1:\n" \
+ : "=d" (__result) \
+ : "d" (__r1), "0" (__r2), "d" (__r3), "d" (__r4), "d" (__r5) \
+ : "memory"); \
+ __result; \
+} )
+
+int eclone(int (*fn)(void *), void *fn_arg, int clone_flags_low,
+ struct clone_args *clone_args, pid_t *pids)
+{
+ struct clone_args my_args;
+ u64 *child_sp;
+ int rc;
+
+ if (clone_args->child_stack) {
+ child_sp = (void *)(clone_args->child_stack +
+ clone_args->child_stack_size);
+ *--child_sp = (u64)fn_arg;
+ *--child_sp = (u64)fn;
+ } else
+ child_sp = (u64 *)0;
+
+ my_args = *clone_args;
+ my_args.child_stack = (unsigned long)child_sp;
+ my_args.child_stack_size = 0;
+
+ rc = do_eclone(flags, pids, &my_args, sizeof(struct clone_args));
+ if (rc < 0) {
+ errno = rc;
+ rc = -1;
+ }
+
+ return rc;
+}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 4/9] user-cr: ppc32 eclone wrapper
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (2 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 3/9] user-cr: s390 " Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
[not found] ` <1258505746-31182-5-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
2009-11-18 0:55 ` [PATCH 5/9] user-cr: add nsexeccwp to test eclone Nathan Lynch
` (5 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
clone_ppc.c | 43 ++++++++++++++++++++++++++++++++
clone_ppc_.S | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 120 insertions(+), 0 deletions(-)
diff --git a/clone_ppc.c b/clone_ppc.c
index 49797fd..c9eee8b 100644
--- a/clone_ppc.c
+++ b/clone_ppc.c
@@ -56,3 +56,46 @@ int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
}
#endif
+
+#include "eclone.h"
+
+extern int __eclone(int (*fn)(void *arg),
+ void *child_sp,
+ int flags,
+ void *fn_arg,
+ struct clone_args *args,
+ size_t args_size,
+ pid_t *pids);
+
+int eclone(int (*fn)(void *), void *fn_arg, int clone_flags_low,
+ struct clone_args *clone_args, pid_t *pids)
+{
+ struct clone_args my_args;
+ unsigned long child_sp;
+ int newpid;
+
+ if (clone_args->child_stack)
+ child_sp = clone_args->child_stack +
+ clone_args->child_stack_size - 1;
+ else
+ child_sp = 0;
+
+ my_args = *clone_args;
+ my_args.child_stack = child_sp;
+ my_args.child_stack_size = 0;
+
+ newpid = __eclone(fn,
+ (void *)child_sp,
+ clone_flags_low,
+ fn_arg,
+ &my_args,
+ sizeof(my_args),
+ pids);
+
+ if (newpid < 0) {
+ errno = -newpid;
+ newpid = -1;
+ }
+
+ return newpid;
+}
diff --git a/clone_ppc_.S b/clone_ppc_.S
index cb3e053..fa89c31 100644
--- a/clone_ppc_.S
+++ b/clone_ppc_.S
@@ -88,3 +88,80 @@ parent:
neg r3,r3
blr
+#ifndef __NR_eclone
+#define __NR_eclone 323
+#endif
+
+/* int [r3] eclone(int (*fn)(void *arg) [r3],
+ * void *child_sp [r4],
+ * int flags [r5],
+ * void *fn_arg [r6],
+ * struct clone_args *args [r7],
+ * size_t args_size [r8],
+ * pid_t *pids [r9]);
+ * Creates a child task with the pids specified by pids.
+ * Returns to parent only, child execution and exit is handled here.
+ * On error, returns negated errno. On success, returns the pid of the child
+ * created.
+ */
+
+.globl __eclone
+__eclone:
+
+ /* No argument validation. */
+
+ /* Set up parent's stack frame. */
+ stwu r1,-32(r1)
+
+ /* Save non-volatiles (r28-r31) which we plan to use. */
+ stmw r28,16(r1)
+
+ /* Set up child's stack frame. */
+ clrrwi r4,r4,4
+ li r0,0
+ stw r0,-16(r4)
+
+ /* Save fn, stack pointer, flags, and fn_arg across system call. */
+ mr r28,r3
+ mr r29,r4
+ mr r30,r5
+ mr r31,r6
+
+ /* Set up arguments for system call. */
+ mr r3,r5 /* flags */
+ mr r4,r7 /* clone_args */
+ mr r5,r8 /* clone_args' size */
+ mr r6,r9 /* pids */
+
+ /* Do the system call */
+ li r0,__NR_eclone
+ sc
+
+ /* Parent or child? */
+ cmpwi cr1,r3,0
+ crandc 4*cr1+eq,4*cr1+eq,4*cr0+so
+ bne cr1,eclone_parent
+
+ /* Child. Call fn. */
+ mtctr r28
+ mr r3,r31
+ bctrl
+
+ /* Assume result of fn in r3 and exit. */
+ li r0,__NR_exit
+ sc
+
+eclone_parent:
+ /* Restore non-volatiles. */
+ lmw r28,16(r1)
+
+ addi r1,r1,32
+
+ /* Return to caller on success. */
+ bnslr
+
+ /* Handle error. Negate the return value to signal an error
+ * to the caller, which must set errno.
+ */
+ neg r3,r3
+ blr
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 5/9] user-cr: add nsexeccwp to test eclone
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (3 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 4/9] user-cr: ppc32 " Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 6/9] user-cr: use eclone API for restart Nathan Lynch
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
From: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
One of the concerns with eclone is whether the stack handling is all
correct and robust enough to withstand real usage. Little testcases
playing with pid values are also necessary, but can't replace really
using clone-with-pids to start a shell from which to keep working.
This patch tweaks the old ns_exec.c namespace manipulation program to
add a -z option to specify a pid. So you can:
nsexeccwp -cmp /bin/bash # start a shell in a new pidns+mntns
mount -t proc proc /proc # mount private /proc
echo $$
1
nsexeccwp -z /bin/bash # start a shell with pid 999
echo $$
999
[ ntl - minor updates to original version to use clone_args/eclone() ]
Signed-off-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
Makefile | 5 +-
clone.h | 54 ++++++++++
nsexeccwp.c | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 387 insertions(+), 1 deletions(-)
create mode 100644 clone.h
create mode 100644 nsexeccwp.c
diff --git a/Makefile b/Makefile
index 181cc1c..32a6893 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ CFLAGS += -g $(WARNS) $(CKPT_INCLUDE) $(DEBUG)
# install dir
INSTALL_DIR = /bin
-PROGS = checkpoint restart ckptinfo
+PROGS = checkpoint restart ckptinfo nsexeccwp
# other cleanup
OTHER = ckptinfo_types.c
@@ -39,11 +39,14 @@ restart: CFLAGS += -D__REENTRANT -pthread
ifneq ($(SUBARCH),)
restart: clone_$(SUBARCH).o
restart: CFLAGS += -DARCH_HAS_CLONE_WITH_PID
+nsexeccwp: clone_$(SUBARCH).o
+nsexeccwp: CFLAGS += -DARCH_HAS_CLONE_WITH_PID
endif
# on powerpc, need also assembly file
ifeq ($(SUBARCH),ppc)
restart: clone_$(SUBARCH)_.o
+nsexeccwp: clone_$(SUBARCH)_.o
endif
# ckptinfo dependencies
diff --git a/clone.h b/clone.h
new file mode 100644
index 0000000..3569a45
--- /dev/null
+++ b/clone.h
@@ -0,0 +1,54 @@
+#ifndef CLONE_H
+#define CLONE_H
+/*
+ * Copyright (C) 2007 IBM Corporation
+ *
+ * Author: Cedric Le Goater <clg-NmTC/0ZBporQT0dZR+AlfA@public.gmane.org>
+ *
+ * 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, version 2 of the
+ * License.
+ *
+ */
+#include <sys/syscall.h>
+
+#ifndef HAVE_UNSHARE
+
+#if __i386__
+# define __NR_unshare 310
+#elif __x86_64__
+# define __NR_unshare 272
+#elif __ia64__
+# define __NR_unshare 1296
+#elif __s390x__
+# define __NR_unshare 303
+#elif __powerpc__
+# define __NR_unshare 282
+#else
+# error "Architecture not supported"
+#endif
+
+#endif /* HAVE_UNSHARE */
+
+#ifndef CLONE_NEWUTS
+#define CLONE_NEWUTS 0x04000000
+#endif
+
+#ifndef CLONE_NEWIPC
+#define CLONE_NEWIPC 0x08000000
+#endif
+
+#ifndef CLONE_NEWUSER
+#define CLONE_NEWUSER 0x10000000
+#endif
+
+#ifndef CLONE_NEWPID
+#define CLONE_NEWPID 0x20000000
+#endif
+
+#ifndef CLONE_NEWNET
+#define CLONE_NEWNET 0x40000000
+#endif
+
+#endif /* CLONE_H */
diff --git a/nsexeccwp.c b/nsexeccwp.c
new file mode 100644
index 0000000..b02c48c
--- /dev/null
+++ b/nsexeccwp.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2008,2009 IBM Corp.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "clone.h"
+#include "eclone.h"
+
+extern pid_t getpgid(pid_t pid);
+extern pid_t getsid(pid_t pid);
+
+static const char* procname;
+
+static void usage(const char *name)
+{
+ printf("usage: %s [-h] [-c] [-mnuUip] [-P <pid-file>]"
+ "[command [arg ..]]\n", name);
+ printf("\n");
+ printf(" -h this message\n");
+ printf("\n");
+ printf(" -z <pid> use clone_with_pids and specify chosen pid\n");
+ printf(" Note that -z and -p are not compatible\n");
+ printf(" -c use 'clone' rather than 'unshare' system call\n");
+ printf(" -g launch in new cgroup\n");
+ printf(" -m mount namespace\n");
+ printf(" -n network namespace\n");
+ printf(" -u utsname namespace\n");
+ printf(" -U userid namespace\n");
+ printf(" -i ipc namespace\n");
+ printf(" -P <pid-file> File in which to write global pid of cinit\n");
+ printf(" -p pid namespace\n");
+ printf(" -f <flag> extra clone flags\n");
+ printf("\n");
+ printf("(C) Copyright IBM Corp. 2006\n");
+ printf("\n");
+ exit(1);
+}
+
+static int string_to_ul(const char *str, unsigned long int *res)
+{
+ char *tail;
+ long long int r;
+
+ if (!*str)
+ return -1;
+
+ errno = 0;
+
+ r = strtol(str, &tail, 16);
+
+ /*
+ * according to strtol(3), if errno is set or tail does no point
+ * to the ending '\0', the conversion failed.
+ */
+ if (errno || *tail)
+ return -1;
+
+ *res = r;
+ return 0;
+}
+
+/*
+ * Copied following opentty() from Fedora's util-linux rpm
+ * I just changed the "FATAL" message below from syslog()
+ * to printf
+ */
+static void
+opentty(const char * tty) {
+ int i, fd, flags;
+
+ fd = open(tty, O_RDWR | O_NONBLOCK);
+ if (fd == -1) {
+ printf("FATAL: can't reopen tty: %s", strerror(errno));
+ sleep(1);
+ exit(1);
+ }
+
+ flags = fcntl(fd, F_GETFL);
+ flags &= ~O_NONBLOCK;
+ fcntl(fd, F_SETFL, flags);
+
+ for (i = 0; i < fd; i++)
+ close(i);
+ for (i = 0; i < 3; i++)
+ if (fd != i)
+ dup2(fd, i);
+ if (fd >= 3)
+ close(fd);
+}
+// Code copy end
+
+int do_newcgrp = 0;
+
+int load_cgroup_dir(char *dest, int len)
+{
+ FILE *f = fopen("/proc/mounts", "r");
+ char buf[200];
+ char *name, *path, *fsname, *options, *p1, *p2, *s;
+ if (!f)
+ return 0;
+ while (fgets(buf, 200, f)) {
+ name = strtok_r(buf, " ", &p1);
+ path = strtok_r(NULL, " ", &p1);
+ fsname = strtok_r(NULL, " ", &p1);
+ options = strtok_r(NULL, " ", &p1);
+ if (strcmp(fsname, "cgroup") != 0)
+ continue;
+
+ /* make sure the freezer is composed */
+ s = strtok_r(options, ",", &p2);
+ while (s && strcmp(s, "freezer") != 0)
+ s = strtok_r(NULL, ",", &p2);
+ if (!s)
+ continue;
+ strncpy(dest, path, len);
+ fclose(f);
+ return 1;
+ }
+ fclose(f);
+ printf("Freezer not mounted\n");
+ return 0;
+}
+
+int move_to_new_cgroup(int newcgroup)
+{
+ char cgroupname[150], cgroupbase[100], tasksfname[200];
+ FILE *fout;
+ int ret;
+
+ if (!load_cgroup_dir(cgroupbase, 100))
+ return 0;
+
+ snprintf(cgroupname, 150, "%s/%d", cgroupbase, newcgroup);
+ ret = mkdir(cgroupname, 0755);
+ if (ret)
+ return 0;
+ snprintf(tasksfname, 200, "%s/tasks", cgroupname);
+ fout = fopen(tasksfname, "w");
+ if (!fout)
+ return 0;
+ fprintf(fout, "%d\n", getpid());
+ fclose(fout);
+ return 1;
+}
+
+int pipefd[2];
+
+/* gah. opentty will close the pipefd */
+int check_newcgrp(void)
+{
+ int ret, newgroup;
+ char buf[20];
+
+ if (!do_newcgrp)
+ return 0;
+
+ close(pipefd[1]);
+ ret = read(pipefd[0], buf, 20);
+ close(pipefd[0]);
+ if (ret == -1) {
+ perror("read");
+ return 1;
+ }
+ newgroup = atoi(buf);
+ if (!move_to_new_cgroup(newgroup))
+ return 1;
+ do_newcgrp = 0;
+ return 0;
+}
+
+int do_child(void *vargv)
+{
+ char **argv = vargv;
+
+ if (check_newcgrp())
+ return 1;
+
+ execve(argv[0], argv, __environ);
+ perror("execve");
+ return 1;
+}
+
+void write_pid(char *pid_file, int pid)
+{
+ FILE *fp;
+
+ if (!pid_file)
+ return;
+
+ fp = fopen(pid_file, "w");
+ if (!fp) {
+ perror("fopen, pid_file");
+ exit(1);
+ }
+ fprintf(fp, "%d", pid);
+ fflush(fp);
+ fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+ int c;
+ unsigned long flags = 0, eflags = 0;
+ char ttyname[256];
+ int status;
+ int ret, use_clone = 0;
+ int pid;
+ char *pid_file = NULL;
+ size_t nr_pids = 1;
+ pid_t chosen_pid = 0;
+
+ procname = basename(argv[0]);
+
+ memset(ttyname, '\0', sizeof(ttyname));
+ readlink("/proc/self/fd/0", ttyname, sizeof(ttyname));
+
+ while ((c = getopt(argc, argv, "+mguUiphz:cnf:P:")) != EOF) {
+ switch (c) {
+ case 'g': do_newcgrp = getpid(); break;
+ case 'm': flags |= CLONE_NEWNS; break;
+ case 'c': use_clone = 1; break;
+ case 'P': pid_file = optarg; break;
+ case 'u': flags |= CLONE_NEWUTS; break;
+ case 'i': flags |= CLONE_NEWIPC; break;
+ case 'U': flags |= CLONE_NEWUSER; break;
+ case 'n': flags |= CLONE_NEWNET; break;
+ case 'p': flags |= CLONE_NEWNS|CLONE_NEWPID; break;
+ case 'z': chosen_pid = atoi(optarg); break;
+ case 'f': if (!string_to_ul(optarg, &eflags)) {
+ flags |= eflags;
+ break;
+ }
+ case 'h':
+ default:
+ usage(procname);
+ }
+ };
+
+ if (chosen_pid) {
+ use_clone = 1;
+ if (flags & CLONE_NEWPID) {
+ printf("Error: can't use CLONE_NEWPID and pick a pid\n");
+ exit(1);
+ }
+ }
+ argv = &argv[optind];
+ argc = argc - optind;
+
+ if (do_newcgrp) {
+ ret = pipe(pipefd);
+ if (ret) {
+ perror("pipe");
+ return -1;
+ }
+ do_newcgrp = pipefd[0];
+ }
+
+ if (use_clone) {
+ struct clone_args clone_args;
+ int stacksize = 4*getpagesize();
+ void *stack = malloc(stacksize);
+
+ if (!stack) {
+ perror("malloc");
+ return -1;
+ }
+
+ memset(&clone_args, 0, sizeof(clone_args));
+ clone_args.child_stack = (unsigned long)stack;
+ clone_args.child_stack_size = stacksize;
+ clone_args.nr_pids = nr_pids;
+
+ printf("about to clone with %lx\n", flags);
+ if (chosen_pid)
+ printf("Will choose pid %d\n", chosen_pid);
+ flags |= SIGCHLD;
+ pid = eclone(do_child, argv, flags, &clone_args, &chosen_pid);
+ if (pid == -1) {
+ perror("clone");
+ return -1;
+ }
+ } else {
+ if ((pid = fork()) == 0) {
+ // Child.
+ //print_my_info(procname, ttyname);
+
+ if (check_newcgrp())
+ return 1;
+ opentty(ttyname);
+
+ printf("about to unshare with %lx\n", flags);
+ ret = unshare(flags);
+ if (ret < 0) {
+ perror("unshare");
+ return 1;
+ }
+
+ return do_child((void*)argv);
+ }
+
+ }
+ if (pid != -1 && do_newcgrp) {
+ char buf[20];
+ snprintf(buf, 20, "%d", pid);
+ close(pipefd[0]);
+ write(pipefd[1], buf, strlen(buf)+1);
+ close(pipefd[1]);
+ }
+
+ write_pid(pid_file, pid);
+
+ if ((ret = waitpid(pid, &status, __WALL)) < 0)
+ printf("waitpid() returns %d, errno %d\n", ret, errno);
+
+ exit(0);
+}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 6/9] user-cr: use eclone API for restart
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (4 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 5/9] user-cr: add nsexeccwp to test eclone Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 7/9] user-cr: remove x86_32 clone_with_pids Nathan Lynch
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Replace use of clone_with_pids with clone_args/eclone. After this the
clone_with_pids support code can go away.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
restart.c | 46 +++++++++++++++-------------------------------
1 files changed, 15 insertions(+), 31 deletions(-)
diff --git a/restart.c b/restart.c
index d5d069a..258cda9 100644
--- a/restart.c
+++ b/restart.c
@@ -34,25 +34,7 @@
#include <linux/checkpoint.h>
#include <linux/checkpoint_hdr.h>
-
-/* this really belongs to some kernel header ! */
-struct pid_set {
- int num_pids;
- pid_t *pids;
-};
-
-/* (until it's supported by libc) from clone_ARCH.c */
-#if defined(__NR_clone_with_pids) && defined(ARCH_HAS_CLONE_WITH_PID)
-extern int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
- struct pid_set *target_pids, void *arg);
-#else
-static int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
- struct pid_set *target_pids, void *arg)
-{
- return clone(fn, child_stack, flags, arg);
-}
-#endif
-
+#include "eclone.h"
static char usage_str[] =
"usage: restart [opts]\n"
@@ -1852,23 +1834,20 @@ int ckpt_fork_stub(void *data)
static pid_t ckpt_fork_child(struct ckpt_ctx *ctx, struct task *child)
{
- struct pid_set pid_set;
- char *stack_region;
- char *stack_start;
+ struct clone_args clone_args;
+ void *stack;
unsigned long flags = SIGCHLD;
+ size_t stack_sz = PTHREAD_STACK_MIN;
+ size_t nr_pids = 1;
pid_t pid = 0;
ckpt_dbg("forking child vpid %d flags %#x\n", child->pid, child->flags);
- stack_region = malloc(PTHREAD_STACK_MIN);
- if (!stack_region) {
+ stack = malloc(stack_sz);
+ if (!stack) {
perror("stack malloc");
return -1;
}
- stack_start = stack_region + PTHREAD_STACK_MIN - 1;
-
- pid_set.pids = &pid;
- pid_set.num_pids = 1;
if (child->flags & TASK_THREAD) {
flags |= CLONE_THREAD | CLONE_SIGHAND | CLONE_VM;
@@ -1893,15 +1872,20 @@ static pid_t ckpt_fork_child(struct ckpt_ctx *ctx, struct task *child)
else
child->real_parent = _getpid();
- pid = clone_with_pids(ckpt_fork_stub, stack_start, flags, &pid_set, child);
+ memset(&clone_args, 0, sizeof(clone_args));
+ clone_args.child_stack = (unsigned long)stack;
+ clone_args.child_stack_size = stack_sz;
+ clone_args.nr_pids = nr_pids;
+
+ pid = eclone(ckpt_fork_stub, child, flags, &clone_args, &pid);
if (pid < 0) {
perror("clone");
- free(stack_region);
+ free(stack);
return -1;
}
if (!(child->flags & TASK_THREAD))
- free(stack_region);
+ free(stack);
ckpt_dbg("forked child vpid %d (asked %d)\n", pid, child->pid);
return pid;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 7/9] user-cr: remove x86_32 clone_with_pids
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (5 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 6/9] user-cr: use eclone API for restart Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 8/9] user-cr: remove s390 clone_with_pids Nathan Lynch
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Remove support code for old clone_with_pids interface and update
comments accordingly.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
clone_x86_32.c | 64 +------------------------------------------------------
1 files changed, 2 insertions(+), 62 deletions(-)
diff --git a/clone_x86_32.c b/clone_x86_32.c
index 61b593c..6f1d891 100644
--- a/clone_x86_32.c
+++ b/clone_x86_32.c
@@ -1,5 +1,5 @@
/*
- * clone_x86_32.c: support for clone_with_pid() on x86_32
+ * clone_x86_32.c: support for eclone() on x86_32
*
* Copyright (C) Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
*
@@ -17,70 +17,10 @@
#include <asm/unistd.h>
/*
- * libc doesn't support clone_with_pid() yet...
+ * libc doesn't support eclone() yet...
* below is arch-dependent code to use the syscall
*/
#include <linux/checkpoint.h>
-#if defined(__NR_clone_with_pids)
-
-/* this really belongs to some kernel header ! */
-struct pid_set {
- int num_pids;
- pid_t *pids;
-};
-
-/* (see: http://lkml.indiana.edu/hypermail/linux/kernel/9604.3/0204.html) */
-int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
- struct pid_set *target_pids, void *arg)
-{
- long retval;
- void **newstack;
-
- /*
- * Set up the stack for child:
- * - the (void *) arg will be the argument for the child function
- * - the fn pointer will be loaded into ebx after the clone
- */
- newstack = (void **) child_stack;
- *--newstack = arg;
- *--newstack = fn;
-
- __asm__ __volatile__(
- "movl %0, %%ebx\n\t" /* flags -> 1st (ebx) */
- "movl %1, %%ecx\n\t" /* newstack -> 2nd (ecx)*/
- "xorl %%edi, %%edi\n\t" /* 0 -> 3rd (edi) */
- "xorl %%edx, %%edx\n\t" /* 0 -> 4th (edx) */
- "pushl %%ebp\n\t" /* save value of ebp */
- "movl %2, %%ebp\n\t" /* flags -> 6th (ebp) */
- :
- :"b" (flags),
- "c" (newstack),
- "r" (target_pids)
- );
-
- __asm__ __volatile__(
- "int $0x80\n\t" /* Linux/i386 system call */
- "testl %0,%0\n\t" /* check return value */
- "jne 1f\n\t" /* jump if parent */
- "popl %%ebx\n\t" /* get subthread function */
- "call *%%ebx\n\t" /* start subthread function */
- "movl %2,%0\n\t"
- "int $0x80\n" /* exit system call: exit subthread */
- "1:\n\t"
- "popl %%ebp\t" /* restore parent's ebp */
- :"=a" (retval)
- :"0" (__NR_clone_with_pids), "i" (__NR_exit)
- :"ebx", "ecx"
- );
-
- if (retval < 0) {
- errno = -retval;
- retval = -1;
- }
- return retval;
-}
-
-#endif
#include "eclone.h"
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 8/9] user-cr: remove s390 clone_with_pids
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (6 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 7/9] user-cr: remove x86_32 clone_with_pids Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-18 0:55 ` [PATCH 9/9] user-cr: remove powerpc clone_with_pids Nathan Lynch
2009-11-25 18:41 ` [PATCH 0/9] user-cr: update to eclone API; add nsexeccwp Oren Laadan
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Remove support code for old clone_with_pids interface and update
comments accordingly.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
clone_s390x.c | 51 ++-------------------------------------------------
1 files changed, 2 insertions(+), 49 deletions(-)
diff --git a/clone_s390x.c b/clone_s390x.c
index 5ed6f15..af3d41f 100644
--- a/clone_s390x.c
+++ b/clone_s390x.c
@@ -1,5 +1,5 @@
/*
- * clone_s390.c: support for clone_with_pid() on s390x (64 bit)
+ * clone_s390.c: support for eclone() on s390x (64 bit)
*
* Copyright (C) IBM Corporation
*
@@ -19,57 +19,10 @@
#include <asm/unistd.h>
/*
- * libc doesn't support clone_with_pid() yet...
+ * libc doesn't support eclone() yet...
* below is arch-dependent code to use the syscall
*/
#include <linux/checkpoint.h>
-#if defined(__NR_clone_with_pids)
-
-/* this really belongs to some kernel header ! */
-struct pid_set {
- int num_pids;
- pid_t *pids;
-};
-
-/* (see: http://lkml.indiana.edu/hypermail/linux/kernel/9604.3/0204.html) */
-
-#define do_clone_with_pids(stack, flags, ptid, ctid, setp) ({ \
- register unsigned long int __r2 asm ("2") = (unsigned long int)(stack);\
- register unsigned long int __r3 asm ("3") = (unsigned long int)(flags);\
- register unsigned long int __r4 asm ("4") = (unsigned long int)(ptid); \
- register unsigned long int __r5 asm ("5") = (unsigned long int)(ctid); \
- register unsigned long int __r6 asm ("6") = (unsigned long int)(NULL); \
- register unsigned long int __r7 asm ("7") = (unsigned long int)(setp); \
- register unsigned long int __result asm ("2"); \
- __asm__ __volatile__( \
- " lghi %%r1,%7\n" \
- " svc 0\n" \
- : "=d" (__result) \
- : "0" (__r2), "d" (__r3), \
- "d" (__r4), "d" (__r5), "d" (__r6), "d" (__r7), \
- "i" (__NR_clone_with_pids) \
- : "1", "cc", "memory" \
- ); \
- __result; \
- })
-
-int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
- struct pid_set *target_pids, void *arg)
-{
- long retval;
- retval = do_clone_with_pids(child_stack, flags, NULL, NULL,
- target_pids);
-
- if (retval < 0) {
- errno = -retval;
- return -1;
- } else if (retval == 0) {
- return fn(arg);
- } else
- return retval;
-}
-
-#endif /* !defined(__NR_clone_with_pids) */
#include "eclone.h"
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 9/9] user-cr: remove powerpc clone_with_pids
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (7 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 8/9] user-cr: remove s390 clone_with_pids Nathan Lynch
@ 2009-11-18 0:55 ` Nathan Lynch
2009-11-25 18:41 ` [PATCH 0/9] user-cr: update to eclone API; add nsexeccwp Oren Laadan
9 siblings, 0 replies; 16+ messages in thread
From: Nathan Lynch @ 2009-11-18 0:55 UTC (permalink / raw)
To: containers-qjLDD68F18O7TbgM5vRIOg
Cc: Oren-FOgKQjlUJ6BQetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
Sukadev Bhattiprolu
Remove C and asm support code for old clone_with_pids interface and
update comments accordingly.
Signed-off-by: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
---
clone_ppc.c | 37 +--------------------------
clone_ppc_.S | 79 +---------------------------------------------------------
2 files changed, 2 insertions(+), 114 deletions(-)
diff --git a/clone_ppc.c b/clone_ppc.c
index c9eee8b..47b8290 100644
--- a/clone_ppc.c
+++ b/clone_ppc.c
@@ -16,46 +16,11 @@
#include <sys/syscall.h>
#include <asm/unistd.h>
-struct target_pid_set;
-
-extern int __clone_with_pids(int (*fn)(void *arg),
- void *child_stack ,
- int flags,
- void *arg,
- void *parent_tid,
- void *tls,
- void *child_tid,
- struct target_pid_set *setp);
-
/*
- * libc doesn't support clone_with_pid() yet...
+ * libc doesn't support eclone() yet...
* below is arch-dependent code to use the syscall
*/
#include <linux/checkpoint.h>
-#if defined(__NR_clone_with_pids)
-
-/* (see: http://lkml.indiana.edu/hypermail/linux/kernel/9604.3/0204.html) */
-
-int clone_with_pids(int (*fn)(void *), void *child_stack, int flags,
- struct target_pid_set *target_pids, void *arg)
-{
- void *parent_tid = NULL;
- void *tls = NULL;
- void *child_tid = NULL;
- pid_t newpid;
-
- newpid = __clone_with_pids(fn, child_stack, flags, arg, parent_tid,
- tls, child_tid, target_pids);
-
- if (newpid < 0) {
- errno = -newpid;
- return -1;
- }
-
- return newpid;
-}
-
-#endif
#include "eclone.h"
diff --git a/clone_ppc_.S b/clone_ppc_.S
index fa89c31..b736e13 100644
--- a/clone_ppc_.S
+++ b/clone_ppc_.S
@@ -1,5 +1,5 @@
/*
- * clone_ppc_.S: support for clone_with_pid() on powerpc (32 bit)
+ * clone_ppc_.S: ppc32 support for eclone()
*
* Author: Nathan Lynch <ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
*
@@ -11,83 +11,6 @@
#include <asm/unistd.h>
#include "powerpc_asm.h"
-/* int [r3] clone_with_pids(int (*fn)(void *arg) [r3],
- * void *child_stack [r4],
- * int flags [r5],
- * void *arg [r6],
- * void *parent_tid [r7],
- * void *tls [r8],
- * void *child_tid [r9],
- * struct target_pid_set *setp [r10]);
- * Creates a child task with the pids specified by setp.
- * Returns to parent only, child execution and exit is handled here.
- * On error, returns negated errno. On success, returns the pid of the child
- * created.
- */
-
-.text
-.globl __clone_with_pids
-__clone_with_pids:
-
-/* No argument validation. */
-
-/* Set up parent's stack frame. */
-stwu r1,-32(r1)
-
- /* Save non-volatiles (r28-r31) which we plan to use. */
- stmw r28,16(r1)
-
- /* Set up child's stack frame. */
- clrrwi r4,r4,4
- li r0,0
- stw r0,-16(r4)
-
- /* Save fn, stack pointer, flags, and arg across system call. */
- mr r28,r3
- mr r29,r4
- mr r30,r5
- mr r31,r6
-
- /* Set up arguments for system call. Stack pointer is already in r4. */
- mr r3,r5 /* flags */
- mr r5,r7 /* parent_tid */
- mr r6,r8 /* tls */
- mr r7,r9 /* child_tid */
- mr r8,r10 /* setp */
-
- /* Do the system call */
- li r0,__NR_clone_with_pids
- sc
-
- /* Parent or child? */
- cmpwi cr1,r3,0
- crandc 4*cr1+eq,4*cr1+eq,4*cr0+so
- bne cr1,parent
-
- /* Child. Call fn. */
- mtctr r28
- mr r3,r31
- bctrl
-
- /* Assume result of fn in r3 and exit. */
- li r0,__NR_exit
- sc
-
-parent:
- /* Restore non-volatiles. */
- lmw r28,16(r1)
-
- addi r1,r1,32
-
- /* Return to caller on success. */
- bnslr
-
- /* Handle error. Negate the return value to signal an error
- * to the caller, which must set errno.
- */
- neg r3,r3
- blr
-
#ifndef __NR_eclone
#define __NR_eclone 323
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 0/9] user-cr: update to eclone API; add nsexeccwp
[not found] ` <1258505746-31182-1-git-send-email-ntl-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>
` (8 preceding siblings ...)
2009-11-18 0:55 ` [PATCH 9/9] user-cr: remove powerpc clone_with_pids Nathan Lynch
@ 2009-11-25 18:41 ` Oren Laadan
9 siblings, 0 replies; 16+ messages in thread
From: Oren Laadan @ 2009-11-25 18:41 UTC (permalink / raw)
To: Nathan Lynch; +Cc: containers-qjLDD68F18O7TbgM5vRIOg, Sukadev Bhattiprolu
Thanks for the port to eclone - this is queued for v19-rc2.
Oren.
Nathan Lynch wrote:
> The following series adds support for eclone to the arch code,
> introduces the nsexeccwp utility which allows for isolated testing of
> eclone's pid-choosing capability, switches the restart utility to
> eclone, and finally phases out the clone_with_pids support code.
>
> I've verified that nsexeccwp works correctly on x86 and powerpc with a
> mainline kernel with eclone support (but not checkpoint/restart); s390
> needs to be built and tested (Serge?).
>
> Based on ckpt-v19-rc1.
>
> Nathan Lynch (8):
> user-cr: add eclone/clone_args header
> user-cr: x86_32 eclone wrapper
> user-cr: s390 eclone wrapper
> user-cr: ppc32 eclone wrapper
> user-cr: use eclone API for restart
> user-cr: remove x86_32 clone_with_pids
> user-cr: remove s390 clone_with_pids
> user-cr: remove powerpc clone_with_pids
>
> Serge E. Hallyn (1):
> user-cr: add nsexeccwp to test eclone
>
> Makefile | 5 +-
> clone.h | 54 +++++++++
> clone_ppc.c | 58 ++++++-----
> clone_ppc_.S | 52 +++++-----
> clone_s390x.c | 97 ++++++++++-------
> clone_x86_32.c | 87 ++++++++-------
> eclone.h | 25 +++++
> nsexeccwp.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> restart.c | 46 +++------
> 9 files changed, 588 insertions(+), 165 deletions(-)
> create mode 100644 clone.h
> create mode 100644 eclone.h
> create mode 100644 nsexeccwp.c
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread