Subject: Re: [vserver] Getting a real pid 1 init in a container
From: Grzegorz Nosek <grzegorz.nosek@gmail.com>
Date: Wed, 21 Mar 2012 16:47:17 +0100
Wed, 21 Mar 2012 16:47:17 +0100
W dniu 21.03.2012 14:56, Grzegorz Nosek pisze:
> I looked through the patch and all this reaper stuff ends up modifying
> vx_info->reaper, which AFAICS is not used anywhere. I downloaded the 3.3
> patch[1] and it looks the same. The relevant function seems to be
> find_new_reaper() from kernel/exit.c as of 2.6.27.y:

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).

It happens because now the container init has itself as the ppid and is 
totally disconnected from the normal process hierarchy. Not quite sure 
how the ppid got set that way, will have another look.

Patch is based on my 2.6.27.y, but looking at 3.3, the function is 
unchanged, except for a lockdep (or something) annotation.

Best regards,
  Grzegorz Nosek


From 4cd7f4f0d7b2b28bc26409e8d8ac4ad427d537d4 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 |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index 45f0658..0049846 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,7 +895,7 @@ 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)
-- 
1.7.2.3