The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at 
https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.1
------>
commit 729323172bc760a2daf4d790a5bffc74ec10c04d
Author: Cyrill Gorcunov <gorcu...@odin.com>
Date:   Tue May 19 00:43:44 2015 +0400

    ve/cgroups: Allow to attach non-self into ve cgroups, v3
    
    In vzctl/libvzctl bundle we restore container like
    
     - create ve/$ctid cgroup
     - move self into this cgroup
     - run criu from inside
    
    So that kernel code passes ve_can_attach test. In turn for
    our P.Haul project (which is managing live migration) the
    situation is different -- it opens ve/$ctid but moves
    criu service pid instead (so that the service will
    start restore procedure). Which leads to situation
    where ve_can_attach fails with -EINVAL.
    
    Basically we need to
    
    1) Check that in case if task is getting attached to
       VE cgroup it should be a single threaded task.
    
    2) In case of multithread task all threads should be
       moved in one pass (this actually prepared by
       cgroup_attach_task caller).
    
    3) In case if VE is stopping or starting only kernel
       threads can attach.
    
    khorenko@:
    Check for thread_group_empty(task) is enough to be sure
    the task is single-threaded.
    
    https://jira.sw.ru/browse/PSBM-33561
    
    Reported-by: Nikita Spiridonov <nspirido...@odin.com>
    Signed-off-by: Cyrill Gorcunov <gorcu...@odin.com>
    
    CC: Vladimir Davydov <vdavy...@odin.com>
    CC: Konstantin Khorenko <khore...@odin.com>
    CC: Pavel Emelyanov <xe...@odin.com>
    CC: Andrey Vagin <ava...@odin.com>
---
 kernel/ve/ve.c | 51 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index e598d15..cf7c848 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -775,24 +775,31 @@ static void ve_destroy(struct cgroup *cg)
 static int ve_can_attach(struct cgroup *cg, struct cgroup_taskset *tset)
 {
        struct ve_struct *ve = cgroup_ve(cg);
-       struct task_struct *task = current;
-
-       if (cgroup_taskset_size(tset) != 1 ||
-           cgroup_taskset_first(tset) != task ||
-           !thread_group_leader(task) ||
-           !thread_group_empty(task))
-               return -EINVAL;
+       struct task_struct *task;
 
        if (ve->is_locked)
                return -EBUSY;
 
        /*
+        * We either moving the whole group of threads,
+        * either a single thread process.
+        */
+       if (cgroup_taskset_size(tset) == 1) {
+               task = cgroup_taskset_first(tset);
+               if (!thread_group_empty(task))
+                       return -EINVAL;
+       }
+
+       /*
         * Forbid userspace tasks to enter during starting or stopping.
-        * Permit attaching kernel threads and init task for this containers.
+        * Permit attaching kernel threads for this containers.
         */
-       if (!ve->is_running && (ve->ve_ns || nr_threads_ve(ve)) &&
-                       !(task->flags & PF_KTHREAD))
-               return -EPIPE;
+       if (!ve->is_running && (ve->ve_ns || nr_threads_ve(ve))) {
+               cgroup_taskset_for_each(task, cg, tset) {
+                       if (!(task->flags & PF_KTHREAD))
+                               return -EPIPE;
+               }
+       }
 
        return 0;
 }
@@ -800,20 +807,22 @@ static int ve_can_attach(struct cgroup *cg, struct 
cgroup_taskset *tset)
 static void ve_attach(struct cgroup *cg, struct cgroup_taskset *tset)
 {
        struct ve_struct *ve = cgroup_ve(cg);
-       struct task_struct *tsk = current;
+       struct task_struct *task;
 
-       /* this probihibts ptracing of task entered to VE from host system */
-       if (ve->is_running && tsk->mm)
-               tsk->mm->vps_dumpable = VD_VE_ENTER_TASK;
+       cgroup_taskset_for_each(task, cg, tset) {
+               /* this probihibts ptracing of task entered to VE from host 
system */
+               if (ve->is_running && task->mm)
+                       task->mm->vps_dumpable = VD_VE_ENTER_TASK;
 
-       /* Drop OOM protection. */
-       tsk->signal->oom_score_adj = 0;
-       tsk->signal->oom_score_adj_min = 0;
+               /* Drop OOM protection. */
+               task->signal->oom_score_adj = 0;
+               task->signal->oom_score_adj_min = 0;
 
-       /* Leave parent exec domain */
-       tsk->parent_exec_id--;
+               /* Leave parent exec domain */
+               task->parent_exec_id--;
 
-       tsk->task_ve = ve;
+               task->task_ve = ve;
+       }
 }
 
 static int ve_state_read(struct cgroup *cg, struct cftype *cft,
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to