Wed, 21 Mar 2012 19:22:20 +0100
W dniu 21.03.2012 16:47, Grzegorz Nosek pisze:
> A basically working patch attached. One weird side effect is that the
> container init and its children are not visible in `vps auxf` (they
> remain visible in `vps aux` though).
Attached v2, this one is actually working *too* well -- the process tree
is shown *twice* on some occasions ;) Also, upstart works like a charm
(start/stop etc.)
This is another bug I won't fix today -- gotta go:
debian:/proc/sys/vserver# grep Tgid /proc/1/status
Tgid: 1
debian:/proc/sys/vserver# chcontext --xid 1 -- grep Tgid /proc/1/status
Tgid: 1
debian:/proc/sys/vserver# chcontext --xid 948 -- grep Tgid /proc/1/status
Tgid: 1
debian:/proc/sys/vserver# chcontext --xid 1 -- grep Tgid /proc/1/status
Tgid: 2219
Basically in xid==1 /proc/1 contains info about the last visited fakeinit.
Best regards,
Grzegorz Nosek
From c897c155a81ad4c9689b7f9936d68b08554063cd Mon Sep 17 00:00:00 2001
From: Grzegorz Nosek <root@localdomain.pl>
Date: Wed, 21 Mar 2012 15:45:08 +0100
Subject: [PATCH] Actually use VServer context reaper
---
kernel/exit.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/kernel/exit.c b/kernel/exit.c
index 45f0658..e1bfed0 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -859,6 +859,8 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
{
struct pid_namespace *pid_ns = task_active_pid_ns(father);
struct task_struct *thread;
+ struct vx_info *vxi = father->vx_info;
+ struct task_struct *reaper;
thread = father;
while_each_thread(father, thread) {
@@ -869,6 +871,15 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
return thread;
}
+ reaper = pid_ns->child_reaper;
+ if (vxi) {
+ BUG_ON(!vxi->vx_reaper);
+ if (vxi->vx_reaper != init_pid_ns.child_reaper &&
+ vxi->vx_reaper != father) {
+ reaper = vxi->vx_reaper;
+ }
+ }
+
if (unlikely(pid_ns->child_reaper == father)) {
write_unlock_irq(&tasklist_lock);
if (unlikely(pid_ns == &init_pid_ns))
@@ -884,12 +895,12 @@ static struct task_struct *find_new_reaper(struct task_struct
*father)
pid_ns->child_reaper = init_pid_ns.child_reaper;
}
- return pid_ns->child_reaper;
+ return reaper;
}
static void forget_original_parent(struct task_struct *father)
{
- struct task_struct *p, *n, *reaper;
+ struct task_struct *p, *n, *reaper, *new_parent;
LIST_HEAD(ptrace_dead);
write_lock_irq(&tasklist_lock);
@@ -900,7 +911,11 @@ static void forget_original_parent(struct task_struct *father)
ptrace_exit(father, &ptrace_dead);
list_for_each_entry_safe(p, n, &father->children, sibling) {
- p->real_parent = reaper;
+ new_parent = reaper;
+ if (unlikely(p == reaper))
+ new_parent = task_active_pid_ns(p)->child_reaper;
+
+ p->real_parent = new_parent;
if (p->parent == father) {
BUG_ON(p->ptrace);
p->parent = p->real_parent;
--
1.7.2.3