* [RFC][v4][PATCH 0/7] clone_extended() syscall
@ 2009-08-06 6:10 Sukadev Bhattiprolu
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:10 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Define clone_extended() system call (previously known as clone_with_pids()).
See patch 7/7 for details. (Other patches are same as before).
Changelog [v4]:
- Rename system call to clone_extended() and support 64bit clone-flags
- Rename 'struct target_pid_set' to 'struct pid_set'
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 1/7] Factor out code to allocate pidmap page
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 6:22 ` Sukadev Bhattiprolu
2009-08-06 6:23 ` [RFC][v4][PATCH 2/7]: Have alloc_pidmap() return actual error code Sukadev Bhattiprolu
` (5 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:22 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 1/7] Factor out code to allocate pidmap page
To implement support for clone_with_pids() system call we would
need to allocate pidmap page in more than one place. Move this
code to a new function alloc_pidmap_page().
Changelog[v2]:
- (Matt Helsley, Dave Hansen) Have alloc_pidmap_page() return
-ENOMEM on error instead of -1.
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
kernel/pid.c | 46 ++++++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 16 deletions(-)
Index: linux-2.6/kernel/pid.c
===================================================================
--- linux-2.6.orig/kernel/pid.c 2009-08-05 17:00:22.000000000 -0700
+++ linux-2.6/kernel/pid.c 2009-08-05 17:02:40.000000000 -0700
@@ -122,9 +122,34 @@
atomic_inc(&map->nr_free);
}
+static int alloc_pidmap_page(struct pidmap *map)
+{
+ void *page;
+
+ if (likely(map->page))
+ return 0;
+
+ page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+
+ /*
+ * Free the page if someone raced with us installing it:
+ */
+ spin_lock_irq(&pidmap_lock);
+ if (map->page)
+ kfree(page);
+ else
+ map->page = page;
+ spin_unlock_irq(&pidmap_lock);
+
+ if (unlikely(!map->page))
+ return -ENOMEM;
+
+ return 0;
+}
+
static int alloc_pidmap(struct pid_namespace *pid_ns)
{
- int i, offset, max_scan, pid, last = pid_ns->last_pid;
+ int i, rc, offset, max_scan, pid, last = pid_ns->last_pid;
struct pidmap *map;
pid = last + 1;
@@ -134,21 +159,10 @@
map = &pid_ns->pidmap[pid/BITS_PER_PAGE];
max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
for (i = 0; i <= max_scan; ++i) {
- if (unlikely(!map->page)) {
- void *page = kzalloc(PAGE_SIZE, GFP_KERNEL);
- /*
- * Free the page if someone raced with us
- * installing it:
- */
- spin_lock_irq(&pidmap_lock);
- if (map->page)
- kfree(page);
- else
- map->page = page;
- spin_unlock_irq(&pidmap_lock);
- if (unlikely(!map->page))
- break;
- }
+ rc = alloc_pidmap_page(map);
+ if (rc)
+ break;
+
if (likely(atomic_read(&map->nr_free))) {
do {
if (!test_and_set_bit(offset, map->page)) {
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 2/7]: Have alloc_pidmap() return actual error code
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 6:22 ` [RFC][v4][PATCH 1/7] Factor out code to allocate pidmap page Sukadev Bhattiprolu
@ 2009-08-06 6:23 ` Sukadev Bhattiprolu
2009-08-06 6:23 ` [RFC][v4][PATCH 3/7]: Add target_pid parameter to alloc_pidmap() Sukadev Bhattiprolu
` (4 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:23 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 2/7]: Have alloc_pidmap() return actual error code
alloc_pidmap() can fail either because all pid numbers are in use or
because memory allocation failed. With support for setting a specific
pid number, alloc_pidmap() would also fail if either the given pid
number is invalid or in use.
Rather than have callers assume -ENOMEM, have alloc_pidmap() return
the actual error.
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
kernel/fork.c | 5 +++--
kernel/pid.c | 9 ++++++---
2 files changed, 9 insertions(+), 5 deletions(-)
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 17:00:22.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-05 17:02:45.000000000 -0700
@@ -1124,10 +1124,11 @@
goto bad_fork_cleanup_io;
if (pid != &init_struct_pid) {
- retval = -ENOMEM;
pid = alloc_pid(p->nsproxy->pid_ns);
- if (!pid)
+ if (IS_ERR(pid)) {
+ retval = PTR_ERR(pid);
goto bad_fork_cleanup_io;
+ }
if (clone_flags & CLONE_NEWPID) {
retval = pid_ns_prepare_proc(p->nsproxy->pid_ns);
Index: linux-2.6/kernel/pid.c
===================================================================
--- linux-2.6.orig/kernel/pid.c 2009-08-05 17:02:40.000000000 -0700
+++ linux-2.6/kernel/pid.c 2009-08-05 17:02:45.000000000 -0700
@@ -158,6 +158,7 @@
offset = pid & BITS_PER_PAGE_MASK;
map = &pid_ns->pidmap[pid/BITS_PER_PAGE];
max_scan = (pid_max + BITS_PER_PAGE - 1)/BITS_PER_PAGE - !offset;
+ rc = -EAGAIN;
for (i = 0; i <= max_scan; ++i) {
rc = alloc_pidmap_page(map);
if (rc)
@@ -188,12 +189,14 @@
} else {
map = &pid_ns->pidmap[0];
offset = RESERVED_PIDS;
- if (unlikely(last == offset))
+ if (unlikely(last == offset)) {
+ rc = -EAGAIN;
break;
+ }
}
pid = mk_pid(pid_ns, map, offset);
}
- return -1;
+ return rc;
}
int next_pidmap(struct pid_namespace *pid_ns, int last)
@@ -298,7 +301,7 @@
free_pidmap(pid->numbers + i);
kmem_cache_free(ns->pid_cachep, pid);
- pid = NULL;
+ pid = ERR_PTR(nr);
goto out;
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 3/7]: Add target_pid parameter to alloc_pidmap()
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 6:22 ` [RFC][v4][PATCH 1/7] Factor out code to allocate pidmap page Sukadev Bhattiprolu
2009-08-06 6:23 ` [RFC][v4][PATCH 2/7]: Have alloc_pidmap() return actual error code Sukadev Bhattiprolu
@ 2009-08-06 6:23 ` Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 4/7]: Add target_pids parameter to alloc_pid() Sukadev Bhattiprolu
` (3 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:23 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 3/7]: Add target_pid parameter to alloc_pidmap()
With support for setting a specific pid number for a process,
alloc_pidmap() will need a paramter a 'target_pid' parameter.
Changelog[v2]:
- (Serge Hallyn) Check for 'pid < 0' in set_pidmap().(Code
actually checks for 'pid <= 0' for completeness).
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
kernel/pid.c | 28 ++++++++++++++++++++++++++--
1 files changed, 26 insertions(+), 2 deletions(-)
Index: linux-2.6/kernel/pid.c
===================================================================
--- linux-2.6.orig/kernel/pid.c 2009-08-05 17:02:45.000000000 -0700
+++ linux-2.6/kernel/pid.c 2009-08-05 19:34:37.000000000 -0700
@@ -147,11 +147,35 @@
return 0;
}
-static int alloc_pidmap(struct pid_namespace *pid_ns)
+static int set_pidmap(struct pid_namespace *pid_ns, int pid)
+{
+ int offset;
+ struct pidmap *map;
+
+ if (pid <= 0 || pid >= pid_max)
+ return -EINVAL;
+
+ offset = pid & BITS_PER_PAGE_MASK;
+ map = &pid_ns->pidmap[pid/BITS_PER_PAGE];
+
+ if (alloc_pidmap_page(map))
+ return -ENOMEM;
+
+ if (test_and_set_bit(offset, map->page))
+ return -EBUSY;
+
+ atomic_dec(&map->nr_free);
+ return pid;
+}
+
+static int alloc_pidmap(struct pid_namespace *pid_ns, int target_pid)
{
int i, rc, offset, max_scan, pid, last = pid_ns->last_pid;
struct pidmap *map;
+ if (target_pid)
+ return set_pidmap(pid_ns, target_pid);
+
pid = last + 1;
if (pid >= pid_max)
pid = RESERVED_PIDS;
@@ -270,7 +294,7 @@
tmp = ns;
for (i = ns->level; i >= 0; i--) {
- nr = alloc_pidmap(tmp);
+ nr = alloc_pidmap(tmp, 0);
if (nr < 0)
goto out_free;
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 4/7]: Add target_pids parameter to alloc_pid()
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2009-08-06 6:23 ` [RFC][v4][PATCH 3/7]: Add target_pid parameter to alloc_pidmap() Sukadev Bhattiprolu
@ 2009-08-06 6:24 ` Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 5/7]: Add target_pids parameter to copy_process() Sukadev Bhattiprolu
` (2 subsequent siblings)
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:24 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 4/7]: Add target_pids parameter to alloc_pid()
This parameter is currently NULL, but will be used in a follow-on patch.
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
include/linux/pid.h | 2 +-
kernel/fork.c | 3 ++-
kernel/pid.c | 9 +++++++--
3 files changed, 10 insertions(+), 4 deletions(-)
Index: linux-2.6/include/linux/pid.h
===================================================================
--- linux-2.6.orig/include/linux/pid.h 2009-08-05 19:34:37.000000000 -0700
+++ linux-2.6/include/linux/pid.h 2009-08-05 19:35:08.000000000 -0700
@@ -119,7 +119,7 @@
extern struct pid *find_ge_pid(int nr, struct pid_namespace *);
int next_pidmap(struct pid_namespace *pid_ns, int last);
-extern struct pid *alloc_pid(struct pid_namespace *ns);
+extern struct pid *alloc_pid(struct pid_namespace *ns, pid_t *target_pids);
extern void free_pid(struct pid *pid);
/*
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:34:37.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-05 19:35:08.000000000 -0700
@@ -954,6 +954,7 @@
int retval;
struct task_struct *p;
int cgroup_callbacks_done = 0;
+ pid_t *target_pids = NULL;
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
@@ -1124,7 +1125,7 @@
goto bad_fork_cleanup_io;
if (pid != &init_struct_pid) {
- pid = alloc_pid(p->nsproxy->pid_ns);
+ pid = alloc_pid(p->nsproxy->pid_ns, target_pids);
if (IS_ERR(pid)) {
retval = PTR_ERR(pid);
goto bad_fork_cleanup_io;
Index: linux-2.6/kernel/pid.c
===================================================================
--- linux-2.6.orig/kernel/pid.c 2009-08-05 19:34:37.000000000 -0700
+++ linux-2.6/kernel/pid.c 2009-08-05 19:35:08.000000000 -0700
@@ -280,13 +280,14 @@
call_rcu(&pid->rcu, delayed_put_pid);
}
-struct pid *alloc_pid(struct pid_namespace *ns)
+struct pid *alloc_pid(struct pid_namespace *ns, pid_t *target_pids)
{
struct pid *pid;
enum pid_type type;
int i, nr;
struct pid_namespace *tmp;
struct upid *upid;
+ int tpid;
pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
if (!pid)
@@ -294,7 +295,11 @@
tmp = ns;
for (i = ns->level; i >= 0; i--) {
- nr = alloc_pidmap(tmp, 0);
+ tpid = 0;
+ if (target_pids)
+ tpid = target_pids[i];
+
+ nr = alloc_pidmap(tmp, tpid);
if (nr < 0)
goto out_free;
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 5/7]: Add target_pids parameter to copy_process()
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
` (3 preceding siblings ...)
2009-08-06 6:24 ` [RFC][v4][PATCH 4/7]: Add target_pids parameter to alloc_pid() Sukadev Bhattiprolu
@ 2009-08-06 6:24 ` Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 6/7]: Define do_fork_with_pids() Sukadev Bhattiprolu
2009-08-06 6:25 ` [RFC][v4][PATCH 7/7]: Define clone_extended() syscall Sukadev Bhattiprolu
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:24 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 5/7]: Add target_pids parameter to copy_process()
The new parameter will be used in a follow-on patch when clone_with_pids()
is implemented.
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
kernel/fork.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:35:08.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-05 19:35:34.000000000 -0700
@@ -949,12 +949,12 @@
unsigned long stack_size,
int __user *child_tidptr,
struct pid *pid,
+ pid_t *target_pids,
int trace)
{
int retval;
struct task_struct *p;
int cgroup_callbacks_done = 0;
- pid_t *target_pids = NULL;
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
@@ -1330,7 +1330,7 @@
struct pt_regs regs;
task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL,
- &init_struct_pid, 0);
+ &init_struct_pid, NULL, 0);
if (!IS_ERR(task))
init_idle(task, cpu);
@@ -1353,6 +1353,7 @@
struct task_struct *p;
int trace = 0;
long nr;
+ pid_t *target_pids = NULL;
/*
* Do some preliminary argument and permissions checking before we
@@ -1393,7 +1394,7 @@
trace = tracehook_prepare_clone(clone_flags);
p = copy_process(clone_flags, stack_start, regs, stack_size,
- child_tidptr, NULL, trace);
+ child_tidptr, NULL, target_pids, trace);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
` (4 preceding siblings ...)
2009-08-06 6:24 ` [RFC][v4][PATCH 5/7]: Add target_pids parameter to copy_process() Sukadev Bhattiprolu
@ 2009-08-06 6:24 ` Sukadev Bhattiprolu
2009-08-06 6:25 ` [RFC][v4][PATCH 7/7]: Define clone_extended() syscall Sukadev Bhattiprolu
6 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:24 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
do_fork_with_pids() is same as do_fork(), except that it takes an
additional, 'pid_set', parameter. This parameter, currently unused,
specifies the set of target pids of the process in each of its pid
namespaces.
Changelog[v3]:
- Fix "long-line" warning from checkpatch.pl
Changelog[v2]:
- To facilitate moving architecture-inpdendent code to kernel/fork.c
pass in 'struct target_pid_set __user *' to do_fork_with_pids()
rather than 'pid_t *' (next patch moves the arch-independent
code to kernel/fork.c)
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
include/linux/sched.h | 3 +++
include/linux/types.h | 5 +++++
kernel/fork.c | 16 ++++++++++++++--
3 files changed, 22 insertions(+), 2 deletions(-)
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/sched.h 2009-08-05 19:36:59.000000000 -0700
@@ -2053,6 +2053,9 @@
extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
+extern long do_fork_with_pids(unsigned long, unsigned long, struct pt_regs *,
+ unsigned long, int __user *, int __user *,
+ struct pid_set __user *pid_set);
struct task_struct *fork_idle(int);
extern void set_task_comm(struct task_struct *tsk, char *from);
Index: linux-2.6/include/linux/types.h
===================================================================
--- linux-2.6.orig/include/linux/types.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/types.h 2009-08-05 19:55:42.000000000 -0700
@@ -204,6 +204,11 @@
char f_fpack[6];
};
+struct pid_set {
+ int num_pids;
+ pid_t *pids;
+};
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:35:34.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-05 19:55:42.000000000 -0700
@@ -1343,12 +1343,13 @@
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
-long do_fork(unsigned long clone_flags,
+long do_fork_with_pids(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
- int __user *child_tidptr)
+ int __user *child_tidptr,
+ struct pid_set __user *pid_setp)
{
struct task_struct *p;
int trace = 0;
@@ -1451,6 +1452,17 @@
return nr;
}
+long do_fork(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size,
+ int __user *parent_tidptr,
+ int __user *child_tidptr)
+{
+ return do_fork_with_pids(clone_flags, stack_start, regs, stack_size,
+ parent_tidptr, child_tidptr, NULL);
+}
+
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
` (5 preceding siblings ...)
2009-08-06 6:24 ` [RFC][v4][PATCH 6/7]: Define do_fork_with_pids() Sukadev Bhattiprolu
@ 2009-08-06 6:25 ` Sukadev Bhattiprolu
[not found] ` <20090806062505.GG5619-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
6 siblings, 1 reply; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 6:25 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Alexey Dobriyan
Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
Container restart requires that a task have the same pid it had when it was
checkpointed. When containers are nested the tasks within the containers
exist in multiple pid namespaces and hence have multiple pids to specify
during restart.
This patch defines, a new system call, clone_extended() which is like clone(),
but takes a new 'pid_set' parameter. This parameter lets caller choose
specific pid numbers for the child process, in the process's active and
ancestor pid namespaces. (Descendant pid namespaces in general don't matter
since processes don't have pids in them anyway, but see comments in
copy_target_pids() regarding CLONE_NEWPID).
Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
now, to prevent unprivileged processes from misusing this interface.
While the main motivation for this interface is the need to let a process
choose its 'pid numbers', the clone_extended() interface uses 64-bit clone
flags. The 'higher' portion of the clone flags are unused and are only
included to preclude yet another version of clone when a new clone flag is
needed.
===== Interface:
Compared to clone(), clone_extended() needs to pass in three more pieces
of information:
- additional 32-bit of clone_flags
- number of pids in the set
- user buffer containing the list of pids.
But since clone() already takes 5 parameters and some (all ?) architectures
are restricted to 6 parameters to a system-call, additional data-structures
(and copy_from_user()) are needed.
The proposed interface for clone_extended() is:
struct clone_tid_info {
void *parent_tid; /* parent_tid_ptr parameter */
void *child_tid; /* child_tid_ptr parameter */
};
struct pid_set {
int num_pids;
pid_t *pids;
};
int clone_extended(int flags_low, int flags_high, void *child_stack,
void *unused, struct clone_tid_info *tid_ptrs,
struct pid_set *pid_setp);
where:
- flags_low corresponds to the 'flags' parameter in normal clone().
- flags_high is currently unused and meant to be used if/when a new
clone flag is needed.
- 'tid_ptrs' is rather an aribtrary grouping of parameters to keep
total parameter count to 6
- pid_setp specifies the pid-numbers for the process in the different
pid namespaces (discussed further below). We expect 'struct pid_set'
to be useful in other contexts.
- if pid_setp is NULL and flags_high is 0, clone_extended() behaves
like normal clone(), except for an extra copy_from_user() when
'tid_ptrs' is non-NULL.
===== Usage:
int flags_low = (CLONE_FS|CLONE_VM|SIGCHLD);
int flags_high = 0; // unused
pid_t pids[] = { 0, 77, 99 };
struct pid_set pid_set;
int parent_tid;
int child_tid;
struct clone_tid_info tid_ptrs = {&parent_tid, &child_tid};
pid_set.num_pids = sizeof(pids) / sizeof(int);
pid_set.pids = &pids;
syscall(__NR_clone_extended, flags_low, flags_high, stack,
NULL, &tid_ptrs, &pid_set);
===== Notes on 'struct pid_set' parameter
When pid_set is specified and a target-pid (i.e pid_set.pids[i]) is 0,
the kernel continues to assign a pid for the process in that namespace.
In the above example, pids[0] is 0, meaning the kernel will assign next
available pid to the process in init_pid_ns.
But kernel will assign pid 77 in the child pid namespace 1 and pid 99
in pid namespace 2. If either 77 or 99 are taken, the system call fails
with -EBUSY.
If 'pid_set.num_pids' exceeds the current nesting level of pid
namespaces, the system call fails with -EINVAL.
TODO:
- Its mostly an exploratory patch seeking feedback on the interface.
- Gently tested.
- May need additional sanity checks in do_fork_with_pids().
Changelog[v4]:
(address following comments from Serge Hallyn, Oren Laadan).
- Rename interface from clone_with_pids() to clone_extended()
- Add support for clone_flags (define/use 'struct clone_tid_info')
- Rename 'target_pid_set' to simply 'pid_set' since pid_set may be
useful in other contexts.
Changelog[v3]:
- (Oren Laadan) Allow CLONE_NEWPID flag (by allocating an extra pid
in the target_pids[] list and setting it 0. See copy_target_pids()).
- (Oren Laadan) Specified target pids should apply only to youngest
pid-namespaces (see copy_target_pids())
- (Matt Helsley) Update patch description.
Changelog[v2]:
- Remove unnecessary printk and add a note to callers of
copy_target_pids() to free target_pids.
- (Serge Hallyn) Mention CAP_SYS_ADMIN restriction in patch description.
- (Oren Laadan) Add checks for 'num_pids < 0' (return -EINVAL) and
'num_pids == 0' (fall back to normal clone()).
- Move arch-independent code (sanity checks and copy-in of target-pids)
into kernel/fork.c and simplify sys_clone_with_pids()
Changelog[v1]:
- Fixed some compile errors (had fixed these errors earlier in my
git tree but had not refreshed patches before emailing them)
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
---
arch/x86/include/asm/syscalls.h | 2 +
arch/x86/include/asm/unistd_32.h | 1 +
arch/x86/kernel/entry_32.S | 1 +
arch/x86/kernel/process_32.c | 21 +++++++
arch/x86/kernel/syscall_table_32.S | 1 +
kernel/fork.c | 108 +++++++++++++++++++++++++++++++++++-
6 files changed, 133 insertions(+), 1 deletions(-)
Index: linux-2.6/arch/x86/include/asm/syscalls.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/syscalls.h 2009-08-05 19:55:41.000000000 -0700
+++ linux-2.6/arch/x86/include/asm/syscalls.h 2009-08-05 19:56:15.000000000 -0700
@@ -40,6 +40,8 @@
/* kernel/process_32.c */
int sys_clone(struct pt_regs *);
+int sys_clone_extended(struct pt_regs *);
+int sys_vfork(struct pt_regs *);
int sys_execve(struct pt_regs *);
/* kernel/signal.c */
Index: linux-2.6/arch/x86/include/asm/unistd_32.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/unistd_32.h 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/arch/x86/include/asm/unistd_32.h 2009-08-05 19:56:15.000000000 -0700
@@ -342,6 +342,7 @@
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
#define __NR_perf_counter_open 336
+#define __NR_clone_extended 337
#ifdef __KERNEL__
Index: linux-2.6/arch/x86/kernel/entry_32.S
===================================================================
--- linux-2.6.orig/arch/x86/kernel/entry_32.S 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/arch/x86/kernel/entry_32.S 2009-08-05 19:56:15.000000000 -0700
@@ -718,6 +718,7 @@
PTREGSCALL(iopl)
PTREGSCALL(fork)
PTREGSCALL(clone)
+PTREGSCALL(clone_extended)
PTREGSCALL(vfork)
PTREGSCALL(execve)
PTREGSCALL(sigaltstack)
Index: linux-2.6/arch/x86/kernel/process_32.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/process_32.c 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/arch/x86/kernel/process_32.c 2009-08-05 19:56:15.000000000 -0700
@@ -443,6 +443,44 @@
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}
+int sys_clone_extended(struct pt_regs *regs)
+{
+ unsigned long clone_flags_low;
+ unsigned long clone_flags_high;
+ int __user *utids;
+ struct clone_tid_info ktids;
+ unsigned long newsp;
+ int __user *parent_tidptr;
+ int __user *child_tidptr;
+ void __user *upid_setp;
+
+ clone_flags_low = regs->bx;
+ /*
+ * clone_flags_high unused for now. If additional clone flags
+ * are defined, this could be used
+ */
+ clone_flags_high = regs->cx;
+ newsp = regs->dx;
+ utids = (int __user *)regs->di;
+ upid_setp = (void __user *)regs->bp;
+
+ if (!newsp)
+ newsp = regs->sp;
+
+ parent_tidptr = NULL;
+ child_tidptr = NULL;
+ if (utids) {
+ int n = sizeof(struct clone_tid_info);
+ if (copy_from_user(&ktids, utids, n))
+ return -EFAULT;
+ parent_tidptr = ktids.parent_tid;
+ child_tidptr = ktids.child_tid;
+ }
+
+ return do_fork_with_pids(clone_flags_low, newsp, regs, 0, parent_tidptr,
+ child_tidptr, upid_setp);
+}
+
/*
* sys_execve() executes a new program.
*/
Index: linux-2.6/arch/x86/kernel/syscall_table_32.S
===================================================================
--- linux-2.6.orig/arch/x86/kernel/syscall_table_32.S 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/arch/x86/kernel/syscall_table_32.S 2009-08-05 19:56:15.000000000 -0700
@@ -336,3 +336,4 @@
.long sys_pwritev
.long sys_rt_tgsigqueueinfo /* 335 */
.long sys_perf_counter_open
+ .long ptregs_clone_extended
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-05 19:57:10.000000000 -0700
@@ -1338,6 +1338,97 @@
}
/*
+ * If user specified any 'target-pids' in @upid_setp, copy them from
+ * user and return a pointer to a local copy of the list of pids. The
+ * caller must free the list, when they are done using it.
+ *
+ * If user did not specify any target pids, return NULL (caller should
+ * treat this like normal clone).
+ *
+ * On any errors, return the error code
+ */
+static pid_t *copy_target_pids(void __user *upid_setp)
+{
+ int j;
+ int rc;
+ int size;
+ int unum_pids; /* # of pids specified by user */
+ int knum_pids; /* # of pids needed in kernel */
+ pid_t *target_pids;
+ struct pid_set pid_set;
+
+ if (!upid_setp)
+ return NULL;
+
+ rc = copy_from_user(&pid_set, upid_setp, sizeof(pid_set));
+ if (rc)
+ return ERR_PTR(-EFAULT);
+
+ unum_pids = pid_set.num_pids;
+ knum_pids = task_pid(current)->level + 1;
+
+ if (!unum_pids)
+ return NULL;
+
+ if (unum_pids < 0 || unum_pids > knum_pids)
+ return ERR_PTR(-EINVAL);
+
+ /*
+ * To keep alloc_pid() simple, allocate an extra pid_t in target_pids[]
+ * and set it to 0. This last entry in target_pids[] corresponds to the
+ * (yet-to-be-created) descendant pid-namespace if CLONE_NEWPID was
+ * specified. If CLONE_NEWPID was not specified, this last entry will
+ * simply be ignored.
+ */
+ target_pids = kzalloc((knum_pids + 1) * sizeof(pid_t), GFP_KERNEL);
+ if (!target_pids)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * A process running in a level 2 pid namespace has three pid namespaces
+ * and hence three pid numbers. If this process is checkpointed,
+ * information about these three namespaces are saved. We refer to these
+ * namespaces as 'known namespaces'.
+ *
+ * If this checkpointed process is however restarted in a level 3 pid
+ * namespace, the restarted process has an extra ancestor pid namespace
+ * (i.e 'unknown namespace') and 'knum_pids' exceeds 'unum_pids'.
+ *
+ * During restart, the process requests specific pids for its 'known
+ * namespaces' and lets kernel assign pids to its 'unknown namespaces'.
+ *
+ * Since the requested-pids correspond to 'known namespaces' and since
+ * 'known-namespaces' are younger than (i.e descendants of) 'unknown-
+ * namespaces', copy requested pids to the back-end of target_pids[]
+ * (i.e before the last entry for CLONE_NEWPID mentioned above).
+ * Any entries in target_pids[] not corresponding to a requested pid
+ * will be set to zero and kernel assigns a pid in those namespaces.
+ *
+ * NOTE: The order of pids in target_pids[] is oldest pid namespace to
+ * youngest (target_pids[0] corresponds to init_pid_ns). i.e.
+ * the order is:
+ *
+ * - pids for 'unknown-namespaces' (if any)
+ * - pids for 'known-namespaces' (requested pids)
+ * - 0 in the last entry (for CLONE_NEWPID).
+ */
+ j = knum_pids - unum_pids;
+ size = unum_pids * sizeof(pid_t);
+
+ rc = copy_from_user(&target_pids[j], pid_set.pids, size);
+ if (rc) {
+ rc = -EFAULT;
+ goto out_free;
+ }
+
+ return target_pids;
+
+out_free:
+ kfree(target_pids);
+ return ERR_PTR(rc);
+}
+
+/*
* Ok, this is the main fork-routine.
*
* It copies the process, and if successful kick-starts
@@ -1354,7 +1445,7 @@
struct task_struct *p;
int trace = 0;
long nr;
- pid_t *target_pids = NULL;
+ pid_t *target_pids;
/*
* Do some preliminary argument and permissions checking before we
@@ -1388,6 +1479,17 @@
}
}
+ target_pids = copy_target_pids(pid_setp);
+
+ if (target_pids) {
+ if (IS_ERR(target_pids))
+ return PTR_ERR(target_pids);
+
+ nr = -EPERM;
+ if (!capable(CAP_SYS_ADMIN))
+ goto out_free;
+ }
+
/*
* When called from kernel_thread, don't do user tracing stuff.
*/
@@ -1449,6 +1551,10 @@
} else {
nr = PTR_ERR(p);
}
+
+out_free:
+ kfree(target_pids);
+
return nr;
}
Index: linux-2.6/include/linux/types.h
===================================================================
--- linux-2.6.orig/include/linux/types.h 2009-08-05 19:55:42.000000000 -0700
+++ linux-2.6/include/linux/types.h 2009-08-05 19:56:15.000000000 -0700
@@ -209,6 +209,11 @@
pid_t *pids;
};
+struct clone_tid_info {
+ void *parent_tid;
+ void *child_tid;
+};
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806062505.GG5619-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 13:38 ` Serge E. Hallyn
[not found] ` <20090806133847.GA28392-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 20:38 ` Matt Helsley
1 sibling, 1 reply; 18+ messages in thread
From: Serge E. Hallyn @ 2009-08-06 13:38 UTC (permalink / raw)
To: Sukadev Bhattiprolu; +Cc: Containers, Alexey Dobriyan
Quoting Sukadev Bhattiprolu (sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org):
>
> Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
>
> Container restart requires that a task have the same pid it had when it was
> checkpointed. When containers are nested the tasks within the containers
> exist in multiple pid namespaces and hence have multiple pids to specify
> during restart.
>
> This patch defines, a new system call, clone_extended() which is like clone(),
> but takes a new 'pid_set' parameter. This parameter lets caller choose
> specific pid numbers for the child process, in the process's active and
> ancestor pid namespaces. (Descendant pid namespaces in general don't matter
> since processes don't have pids in them anyway, but see comments in
> copy_target_pids() regarding CLONE_NEWPID).
>
> Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
> now, to prevent unprivileged processes from misusing this interface.
It only needs that when specifying pids.
> While the main motivation for this interface is the need to let a process
> choose its 'pid numbers', the clone_extended() interface uses 64-bit clone
> flags. The 'higher' portion of the clone flags are unused and are only
> included to preclude yet another version of clone when a new clone flag is
> needed.
>
> ===== Interface:
>
> Compared to clone(), clone_extended() needs to pass in three more pieces
> of information:
>
> - additional 32-bit of clone_flags
> - number of pids in the set
> - user buffer containing the list of pids.
>
> But since clone() already takes 5 parameters and some (all ?) architectures
> are restricted to 6 parameters to a system-call, additional data-structures
> (and copy_from_user()) are needed.
>
> The proposed interface for clone_extended() is:
>
> struct clone_tid_info {
> void *parent_tid; /* parent_tid_ptr parameter */
> void *child_tid; /* child_tid_ptr parameter */
> };
>
> struct pid_set {
> int num_pids;
> pid_t *pids;
> };
>
> int clone_extended(int flags_low, int flags_high, void *child_stack,
> void *unused, struct clone_tid_info *tid_ptrs,
> struct pid_set *pid_setp);
I was thinking additional flags would be passed in the (renamed)
struct pid_set.
-serge
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806133847.GA28392-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 15:37 ` Oren Laadan
[not found] ` <4A7AF8AD.4070805-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Oren Laadan @ 2009-08-06 15:37 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: Containers, Sukadev Bhattiprolu, Alexey Dobriyan
Serge E. Hallyn wrote:
> Quoting Sukadev Bhattiprolu (sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org):
>> Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
>>
>> Container restart requires that a task have the same pid it had when it was
>> checkpointed. When containers are nested the tasks within the containers
>> exist in multiple pid namespaces and hence have multiple pids to specify
>> during restart.
>>
>> This patch defines, a new system call, clone_extended() which is like clone(),
>> but takes a new 'pid_set' parameter. This parameter lets caller choose
>> specific pid numbers for the child process, in the process's active and
>> ancestor pid namespaces. (Descendant pid namespaces in general don't matter
>> since processes don't have pids in them anyway, but see comments in
>> copy_target_pids() regarding CLONE_NEWPID).
>>
>> Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
>> now, to prevent unprivileged processes from misusing this interface.
>
> It only needs that when specifying pids.
>
>> While the main motivation for this interface is the need to let a process
>> choose its 'pid numbers', the clone_extended() interface uses 64-bit clone
>> flags. The 'higher' portion of the clone flags are unused and are only
>> included to preclude yet another version of clone when a new clone flag is
>> needed.
>>
>> ===== Interface:
>>
>> Compared to clone(), clone_extended() needs to pass in three more pieces
>> of information:
>>
>> - additional 32-bit of clone_flags
>> - number of pids in the set
>> - user buffer containing the list of pids.
>>
>> But since clone() already takes 5 parameters and some (all ?) architectures
>> are restricted to 6 parameters to a system-call, additional data-structures
>> (and copy_from_user()) are needed.
>>
>> The proposed interface for clone_extended() is:
>>
>> struct clone_tid_info {
>> void *parent_tid; /* parent_tid_ptr parameter */
>> void *child_tid; /* child_tid_ptr parameter */
>> };
>>
>> struct pid_set {
>> int num_pids;
>> pid_t *pids;
>> };
>>
>> int clone_extended(int flags_low, int flags_high, void *child_stack,
>> void *unused, struct clone_tid_info *tid_ptrs,
>> struct pid_set *pid_setp);
>
> I was thinking additional flags would be passed in the (renamed)
> struct pid_set.
Yes.
But maybe in (renamed) 'struct clone_info' instead of 'struct pid_set' ?
I vaguely recall a strong preference to not require copy-from-user
during a fast-path clone, because it may hurt performance.
*If* this is the case, then maybe place extra flags among the
"base" args, or at least a CLONE_EXTRA would indicate that more
arguments need to be pulled from user-space ?
Do you intend to get feedback from LKML too ?
Oren.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <4A7AF8AD.4070805-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
@ 2009-08-06 15:55 ` Serge E. Hallyn
[not found] ` <20090806155520.GA904-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Serge E. Hallyn @ 2009-08-06 15:55 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Sukadev Bhattiprolu, Alexey Dobriyan
Quoting Oren Laadan (orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org):
>
>
> Serge E. Hallyn wrote:
> > Quoting Sukadev Bhattiprolu (sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org):
> >> Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
> >>
> >> Container restart requires that a task have the same pid it had when it was
> >> checkpointed. When containers are nested the tasks within the containers
> >> exist in multiple pid namespaces and hence have multiple pids to specify
> >> during restart.
> >>
> >> This patch defines, a new system call, clone_extended() which is like clone(),
> >> but takes a new 'pid_set' parameter. This parameter lets caller choose
> >> specific pid numbers for the child process, in the process's active and
> >> ancestor pid namespaces. (Descendant pid namespaces in general don't matter
> >> since processes don't have pids in them anyway, but see comments in
> >> copy_target_pids() regarding CLONE_NEWPID).
> >>
> >> Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
> >> now, to prevent unprivileged processes from misusing this interface.
> >
> > It only needs that when specifying pids.
> >
> >> While the main motivation for this interface is the need to let a process
> >> choose its 'pid numbers', the clone_extended() interface uses 64-bit clone
> >> flags. The 'higher' portion of the clone flags are unused and are only
> >> included to preclude yet another version of clone when a new clone flag is
> >> needed.
> >>
> >> ===== Interface:
> >>
> >> Compared to clone(), clone_extended() needs to pass in three more pieces
> >> of information:
> >>
> >> - additional 32-bit of clone_flags
> >> - number of pids in the set
> >> - user buffer containing the list of pids.
> >>
> >> But since clone() already takes 5 parameters and some (all ?) architectures
> >> are restricted to 6 parameters to a system-call, additional data-structures
> >> (and copy_from_user()) are needed.
> >>
> >> The proposed interface for clone_extended() is:
> >>
> >> struct clone_tid_info {
> >> void *parent_tid; /* parent_tid_ptr parameter */
> >> void *child_tid; /* child_tid_ptr parameter */
> >> };
> >>
> >> struct pid_set {
> >> int num_pids;
> >> pid_t *pids;
> >> };
> >>
> >> int clone_extended(int flags_low, int flags_high, void *child_stack,
> >> void *unused, struct clone_tid_info *tid_ptrs,
> >> struct pid_set *pid_setp);
> >
> > I was thinking additional flags would be passed in the (renamed)
> > struct pid_set.
>
> Yes.
>
> But maybe in (renamed) 'struct clone_info' instead of 'struct pid_set' ?
>
> I vaguely recall a strong preference to not require copy-from-user
> during a fast-path clone, because it may hurt performance.
>
> *If* this is the case, then maybe place extra flags among the
> "base" args, or at least a CLONE_EXTRA would indicate that more
> arguments need to be pulled from user-space ?
Wouldn't passing NULL for struct clone_info suffice?
> Do you intend to get feedback from LKML too ?
>
> Oren.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806155520.GA904-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 16:05 ` Oren Laadan
[not found] ` <4A7AFF61.8050802-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Oren Laadan @ 2009-08-06 16:05 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: Containers, Sukadev Bhattiprolu, Alexey Dobriyan
Serge E. Hallyn wrote:
> Quoting Oren Laadan (orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org):
>>
>> Serge E. Hallyn wrote:
>>> Quoting Sukadev Bhattiprolu (sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org):
>>>> Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
>>>>
>>>> Container restart requires that a task have the same pid it had when it was
>>>> checkpointed. When containers are nested the tasks within the containers
>>>> exist in multiple pid namespaces and hence have multiple pids to specify
>>>> during restart.
>>>>
>>>> This patch defines, a new system call, clone_extended() which is like clone(),
>>>> but takes a new 'pid_set' parameter. This parameter lets caller choose
>>>> specific pid numbers for the child process, in the process's active and
>>>> ancestor pid namespaces. (Descendant pid namespaces in general don't matter
>>>> since processes don't have pids in them anyway, but see comments in
>>>> copy_target_pids() regarding CLONE_NEWPID).
>>>>
>>>> Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
>>>> now, to prevent unprivileged processes from misusing this interface.
>>> It only needs that when specifying pids.
>>>
>>>> While the main motivation for this interface is the need to let a process
>>>> choose its 'pid numbers', the clone_extended() interface uses 64-bit clone
>>>> flags. The 'higher' portion of the clone flags are unused and are only
>>>> included to preclude yet another version of clone when a new clone flag is
>>>> needed.
>>>>
>>>> ===== Interface:
>>>>
>>>> Compared to clone(), clone_extended() needs to pass in three more pieces
>>>> of information:
>>>>
>>>> - additional 32-bit of clone_flags
>>>> - number of pids in the set
>>>> - user buffer containing the list of pids.
>>>>
>>>> But since clone() already takes 5 parameters and some (all ?) architectures
>>>> are restricted to 6 parameters to a system-call, additional data-structures
>>>> (and copy_from_user()) are needed.
>>>>
>>>> The proposed interface for clone_extended() is:
>>>>
>>>> struct clone_tid_info {
>>>> void *parent_tid; /* parent_tid_ptr parameter */
>>>> void *child_tid; /* child_tid_ptr parameter */
>>>> };
>>>>
>>>> struct pid_set {
>>>> int num_pids;
>>>> pid_t *pids;
>>>> };
>>>>
>>>> int clone_extended(int flags_low, int flags_high, void *child_stack,
>>>> void *unused, struct clone_tid_info *tid_ptrs,
>>>> struct pid_set *pid_setp);
>>> I was thinking additional flags would be passed in the (renamed)
>>> struct pid_set.
>> Yes.
>>
>> But maybe in (renamed) 'struct clone_info' instead of 'struct pid_set' ?
>>
>> I vaguely recall a strong preference to not require copy-from-user
>> during a fast-path clone, because it may hurt performance.
>>
>> *If* this is the case, then maybe place extra flags among the
>> "base" args, or at least a CLONE_EXTRA would indicate that more
>> arguments need to be pulled from user-space ?
>
> Wouldn't passing NULL for struct clone_info suffice?
:o
Actually, I misread the original prototype, and I prefer Suka's
current suggestion.
Oren.
>
>> Do you intend to get feedback from LKML too ?
>>
>> Oren.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <4A7AFF61.8050802-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
@ 2009-08-06 16:16 ` Serge E. Hallyn
[not found] ` <20090806161616.GA1472-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Serge E. Hallyn @ 2009-08-06 16:16 UTC (permalink / raw)
To: Oren Laadan; +Cc: Containers, Sukadev Bhattiprolu, Alexey Dobriyan
Quoting Oren Laadan (orenl-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org):
> >>>> The proposed interface for clone_extended() is:
> >>>>
> >>>> struct clone_tid_info {
> >>>> void *parent_tid; /* parent_tid_ptr parameter */
> >>>> void *child_tid; /* child_tid_ptr parameter */
> >>>> };
> >>>>
> >>>> struct pid_set {
> >>>> int num_pids;
> >>>> pid_t *pids;
> >>>> };
> >>>>
> >>>> int clone_extended(int flags_low, int flags_high, void *child_stack,
> >>>> void *unused, struct clone_tid_info *tid_ptrs,
> >>>> struct pid_set *pid_setp);
> >>> I was thinking additional flags would be passed in the (renamed)
> >>> struct pid_set.
> >> Yes.
> >>
> >> But maybe in (renamed) 'struct clone_info' instead of 'struct pid_set' ?
> >>
> >> I vaguely recall a strong preference to not require copy-from-user
> >> during a fast-path clone, because it may hurt performance.
> >>
> >> *If* this is the case, then maybe place extra flags among the
> >> "base" args, or at least a CLONE_EXTRA would indicate that more
> >> arguments need to be pulled from user-space ?
> >
> > Wouldn't passing NULL for struct clone_info suffice?
>
> :o
>
> Actually, I misread the original prototype, and I prefer Suka's
> current suggestion.
I think Suka's suggestion is again inherently limited (in # of
clone flags) and will force even uglier syscalls for each arch than the
previous one already does.
-serge
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806161616.GA1472-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 18:23 ` Sukadev Bhattiprolu
[not found] ` <20090806182340.GA2579-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-06 18:23 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: Containers, Alexey Dobriyan
| I think Suka's suggestion is again inherently limited (in # of
| clone flags) and will force even uglier syscalls for each arch than the
| previous one already does.
|
Yes other architectures are forced to ignore the flags_high and copy-in the
tid pointers.
But if we want more than 64 bit flags, we may need follow the sigset_t
model ?
Also, I am listing three approaches below. Do you prefer #2 below ?
1. =====
struct clone_tid_info {
void *parent_tid; /* parent_tid_ptr parameter */
void *child_tid; /* child_tid_ptr parameter */
};
struct pid_set {
int num_pids;
pid_t *pids;
};
int clone_extended(int flags_low, int flags_high, void *child_stack,
void *unused, struct clone_tid_info *tid_ptrs,
struct pid_set *pid_setp);
2. ======
struct clone_info {
int flags_high;
struct pid_set pid_set;
}
int clone_extended(int flags_low, void *child_stack, void *unused,
int *parent_tid, int *child_tid, struct clone_info *clone_info);
Pros:
- copy_from_user() needed only for new flags and pid_set
Cons:
- splitting the high and low clone-flags is awkward ?
3. =====
typedef struct {
unsigned long flags[N_CLONE_FLAGS];
} clone_flags_t;
int clone_extended(clone_flags_t *flags, void *child_stack, int *unused,
int *parent_tid, int *child_tid, struct pid_set *pid_set);
Pros:
- extendible clone_flags (like sigset_t)
- no copy_from_user() when we have 32 clone-flags
- no copy_from_user for tids
Cons:
- copy_from_user() needed on 32-bit architectures for all flags
when they exceed 32.
Sukadev
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806182340.GA2579-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-06 18:35 ` Serge E. Hallyn
0 siblings, 0 replies; 18+ messages in thread
From: Serge E. Hallyn @ 2009-08-06 18:35 UTC (permalink / raw)
To: Sukadev Bhattiprolu; +Cc: Containers, Alexey Dobriyan
Quoting Sukadev Bhattiprolu (sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org):
> | I think Suka's suggestion is again inherently limited (in # of
> | clone flags) and will force even uglier syscalls for each arch than the
> | previous one already does.
> |
>
> Yes other architectures are forced to ignore the flags_high and copy-in the
> tid pointers.
>
> But if we want more than 64 bit flags, we may need follow the sigset_t
> model ?
>
> Also, I am listing three approaches below. Do you prefer #2 below ?
I prefer #2 with 'struct pid_set' renamed to clone_ext_data or something,
and either a version # or int num_clone_words so we can add clone flags
later. I know, adding more then 32 more clone flags seems unlikely, but...
> 1. =====
>
> struct clone_tid_info {
> void *parent_tid; /* parent_tid_ptr parameter */
> void *child_tid; /* child_tid_ptr parameter */
> };
>
> struct pid_set {
> int num_pids;
> pid_t *pids;
> };
>
> int clone_extended(int flags_low, int flags_high, void *child_stack,
> void *unused, struct clone_tid_info *tid_ptrs,
> struct pid_set *pid_setp);
>
> 2. ======
>
> struct clone_info {
> int flags_high;
> struct pid_set pid_set;
> }
>
> int clone_extended(int flags_low, void *child_stack, void *unused,
> int *parent_tid, int *child_tid, struct clone_info *clone_info);
>
>
> Pros:
> - copy_from_user() needed only for new flags and pid_set
>
> Cons:
> - splitting the high and low clone-flags is awkward ?
>
> 3. =====
>
> typedef struct {
> unsigned long flags[N_CLONE_FLAGS];
> } clone_flags_t;
>
> int clone_extended(clone_flags_t *flags, void *child_stack, int *unused,
> int *parent_tid, int *child_tid, struct pid_set *pid_set);
>
>
> Pros:
> - extendible clone_flags (like sigset_t)
> - no copy_from_user() when we have 32 clone-flags
> - no copy_from_user for tids
>
> Cons:
> - copy_from_user() needed on 32-bit architectures for all flags
> when they exceed 32.
>
>
> Sukadev
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
[not found] ` <20090806062505.GG5619-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 13:38 ` Serge E. Hallyn
@ 2009-08-06 20:38 ` Matt Helsley
1 sibling, 0 replies; 18+ messages in thread
From: Matt Helsley @ 2009-08-06 20:38 UTC (permalink / raw)
To: Sukadev Bhattiprolu; +Cc: Containers, Alexey Dobriyan
On Wed, Aug 05, 2009 at 11:25:05PM -0700, Sukadev Bhattiprolu wrote:
>
> Subject: [RFC][v4][PATCH 7/7]: Define clone_extended() syscall
>
> Container restart requires that a task have the same pid it had when it was
> checkpointed. When containers are nested the tasks within the containers
> exist in multiple pid namespaces and hence have multiple pids to specify
> during restart.
>
> This patch defines, a new system call, clone_extended() which is like clone(),
> but takes a new 'pid_set' parameter. This parameter lets caller choose
> specific pid numbers for the child process, in the process's active and
> ancestor pid namespaces. (Descendant pid namespaces in general don't matter
> since processes don't have pids in them anyway, but see comments in
> copy_target_pids() regarding CLONE_NEWPID).
>
> Unlike clone(), however, clone_extended() needs CAP_SYS_ADMIN, at least for
> now, to prevent unprivileged processes from misusing this interface.
It might be good to describe how, without CAP_SYS_ADMIN, the interface
could be misused (I believe this was Linus' point):
In the status quo, a malicious task must fork rapidly in order to obtain
by trial-and-error the same pid as found in a stale /var/run/foo.pid
file. Without CAP_SYS_ADMIN clone_extended() would remove the
trial-and-error element that loosely protects the system from such
malicious attacks.
Cheers,
-Matt
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
[not found] ` <20090807061103.GA19343-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-07 6:14 ` Sukadev Bhattiprolu
0 siblings, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-07 6:14 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Containers, Eric W. Biederman, hpa-YMNOUZJC4hwAvxtiuMwx3w,
mingo-X9Un+BFzKDI, torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
Alexey Dobriyan, Pavel Emelyanov
Subject: [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
do_fork_with_pids() is same as do_fork(), except that it takes an
additional, 'pid_set', parameter. This parameter, currently unused,
specifies the set of target pids of the process in each of its pid
namespaces.
Changelog[v4]:
- Rename 'struct target_pid_set' to 'struct pid_set' since it may
be useful in other contexts.
Changelog[v3]:
- Fix "long-line" warning from checkpatch.pl
Changelog[v2]:
- To facilitate moving architecture-inpdendent code to kernel/fork.c
pass in 'struct target_pid_set __user *' to do_fork_with_pids()
rather than 'pid_t *' (next patch moves the arch-independent
code to kernel/fork.c)
Signed-off-by: Sukadev Bhattiprolu <sukadev-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
Acked-by: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Oren Laadan <orenl-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
---
include/linux/sched.h | 3 +++
include/linux/types.h | 5 +++++
kernel/fork.c | 16 ++++++++++++++--
3 files changed, 22 insertions(+), 2 deletions(-)
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/sched.h 2009-08-05 19:36:59.000000000 -0700
@@ -2053,6 +2053,9 @@
extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
+extern long do_fork_with_pids(unsigned long, unsigned long, struct pt_regs *,
+ unsigned long, int __user *, int __user *,
+ struct pid_set __user *pid_set);
struct task_struct *fork_idle(int);
extern void set_task_comm(struct task_struct *tsk, char *from);
Index: linux-2.6/include/linux/types.h
===================================================================
--- linux-2.6.orig/include/linux/types.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/types.h 2009-08-06 19:13:38.000000000 -0700
@@ -204,6 +204,11 @@
char f_fpack[6];
};
+struct pid_set {
+ int num_pids;
+ pid_t *pids;
+};
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:35:34.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-06 19:13:38.000000000 -0700
@@ -1343,12 +1343,13 @@
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
-long do_fork(unsigned long clone_flags,
+long do_fork_with_pids(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
- int __user *child_tidptr)
+ int __user *child_tidptr,
+ struct pid_set __user *pid_setp)
{
struct task_struct *p;
int trace = 0;
@@ -1451,6 +1452,17 @@
return nr;
}
+long do_fork(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size,
+ int __user *parent_tidptr,
+ int __user *child_tidptr)
+{
+ return do_fork_with_pids(clone_flags, stack_start, regs, stack_size,
+ parent_tidptr, child_tidptr, NULL);
+}
+
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
2009-08-07 6:11 [RFC][v4][PATCH 0/7] clone_with_pids() system call Sukadev Bhattiprolu
[not found] ` <20090807061103.GA19343-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
@ 2009-08-07 6:14 ` Sukadev Bhattiprolu
1 sibling, 0 replies; 18+ messages in thread
From: Sukadev Bhattiprolu @ 2009-08-07 6:14 UTC (permalink / raw)
To: linux-kernel
Cc: Oren Laadan, Eric W. Biederman, serue, Alexey Dobriyan,
Pavel Emelyanov, Andrew Morton, torvalds, mikew, mingo, hpa,
Containers, sukadev
Subject: [RFC][v4][PATCH 6/7]: Define do_fork_with_pids()
do_fork_with_pids() is same as do_fork(), except that it takes an
additional, 'pid_set', parameter. This parameter, currently unused,
specifies the set of target pids of the process in each of its pid
namespaces.
Changelog[v4]:
- Rename 'struct target_pid_set' to 'struct pid_set' since it may
be useful in other contexts.
Changelog[v3]:
- Fix "long-line" warning from checkpatch.pl
Changelog[v2]:
- To facilitate moving architecture-inpdendent code to kernel/fork.c
pass in 'struct target_pid_set __user *' to do_fork_with_pids()
rather than 'pid_t *' (next patch moves the arch-independent
code to kernel/fork.c)
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Reviewed-by: Oren Laadan <orenl@cs.columbia.edu>
---
include/linux/sched.h | 3 +++
include/linux/types.h | 5 +++++
kernel/fork.c | 16 ++++++++++++++--
3 files changed, 22 insertions(+), 2 deletions(-)
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/sched.h 2009-08-05 19:36:59.000000000 -0700
@@ -2053,6 +2053,9 @@
extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
+extern long do_fork_with_pids(unsigned long, unsigned long, struct pt_regs *,
+ unsigned long, int __user *, int __user *,
+ struct pid_set __user *pid_set);
struct task_struct *fork_idle(int);
extern void set_task_comm(struct task_struct *tsk, char *from);
Index: linux-2.6/include/linux/types.h
===================================================================
--- linux-2.6.orig/include/linux/types.h 2009-08-05 19:34:36.000000000 -0700
+++ linux-2.6/include/linux/types.h 2009-08-06 19:13:38.000000000 -0700
@@ -204,6 +204,11 @@
char f_fpack[6];
};
+struct pid_set {
+ int num_pids;
+ pid_t *pids;
+};
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
Index: linux-2.6/kernel/fork.c
===================================================================
--- linux-2.6.orig/kernel/fork.c 2009-08-05 19:35:34.000000000 -0700
+++ linux-2.6/kernel/fork.c 2009-08-06 19:13:38.000000000 -0700
@@ -1343,12 +1343,13 @@
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
-long do_fork(unsigned long clone_flags,
+long do_fork_with_pids(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
- int __user *child_tidptr)
+ int __user *child_tidptr,
+ struct pid_set __user *pid_setp)
{
struct task_struct *p;
int trace = 0;
@@ -1451,6 +1452,17 @@
return nr;
}
+long do_fork(unsigned long clone_flags,
+ unsigned long stack_start,
+ struct pt_regs *regs,
+ unsigned long stack_size,
+ int __user *parent_tidptr,
+ int __user *child_tidptr)
+{
+ return do_fork_with_pids(clone_flags, stack_start, regs, stack_size,
+ parent_tidptr, child_tidptr, NULL);
+}
+
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2009-08-07 6:14 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-06 6:10 [RFC][v4][PATCH 0/7] clone_extended() syscall Sukadev Bhattiprolu
[not found] ` <20090806061056.GA1044-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 6:22 ` [RFC][v4][PATCH 1/7] Factor out code to allocate pidmap page Sukadev Bhattiprolu
2009-08-06 6:23 ` [RFC][v4][PATCH 2/7]: Have alloc_pidmap() return actual error code Sukadev Bhattiprolu
2009-08-06 6:23 ` [RFC][v4][PATCH 3/7]: Add target_pid parameter to alloc_pidmap() Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 4/7]: Add target_pids parameter to alloc_pid() Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 5/7]: Add target_pids parameter to copy_process() Sukadev Bhattiprolu
2009-08-06 6:24 ` [RFC][v4][PATCH 6/7]: Define do_fork_with_pids() Sukadev Bhattiprolu
2009-08-06 6:25 ` [RFC][v4][PATCH 7/7]: Define clone_extended() syscall Sukadev Bhattiprolu
[not found] ` <20090806062505.GG5619-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 13:38 ` Serge E. Hallyn
[not found] ` <20090806133847.GA28392-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 15:37 ` Oren Laadan
[not found] ` <4A7AF8AD.4070805-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
2009-08-06 15:55 ` Serge E. Hallyn
[not found] ` <20090806155520.GA904-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 16:05 ` Oren Laadan
[not found] ` <4A7AFF61.8050802-RdfvBDnrOixBDgjK7y7TUQ@public.gmane.org>
2009-08-06 16:16 ` Serge E. Hallyn
[not found] ` <20090806161616.GA1472-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 18:23 ` Sukadev Bhattiprolu
[not found] ` <20090806182340.GA2579-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-06 18:35 ` Serge E. Hallyn
2009-08-06 20:38 ` Matt Helsley
-- strict thread matches above, loose matches on Subject: below --
2009-08-07 6:11 [RFC][v4][PATCH 0/7] clone_with_pids() system call Sukadev Bhattiprolu
[not found] ` <20090807061103.GA19343-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-08-07 6:14 ` [RFC][v4][PATCH 6/7]: Define do_fork_with_pids() Sukadev Bhattiprolu
2009-08-07 6:14 ` Sukadev Bhattiprolu
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.