[CRIU] [PATCH] namespace: mark mount namespaces as populated after the forking stage
Pavel Emelyanov
xemul at virtuozzo.com
Thu Jun 16 04:12:29 PDT 2016
On 06/15/2016 07:29 PM, Andrew Vagin wrote:
> On Wed, Jun 15, 2016 at 02:46:52PM +0300, Pavel Emelyanov wrote:
>> On 06/11/2016 09:01 PM, Andrey Vagin wrote:
>>> From: Andrew Vagin <avagin at virtuozzo.com>
>>>
>>> Currently we mark a mount namespaces as populated when a target process
>>> (ns_pid) switches into it. But if a process inherited the right
>>> namespace from a parent, it doesn't call do_restore_task_mnt_ns()
>>> and a namespace can remain unmarked.
>>
>> Why? It should be marked by the task that created one.
>
> What is it create? All namespaces are created by the root task.
I don't get the "and a namespace remain unmarked" problem.
> All these don't matter with this patch.
>
>>
>>> af55c059fb6 ("mount: fix a race between restoring namespaces and file mappings")
>>> After this patch we could simplify logic around ns_populated. Currently
>>> it's a futex, but nodoby waits on it. We can set ns_populated when we
>>> are going to close namespace descriptors. To avoid additional locks, we
>>> can do this when all task pass the forking stage and don't start the
>>> next stage.
>>
>> Don't we need barriers between ns->populated = true and close(ns->fd)?
>
> We don't need, because we set ns_populated when all task are stopped.
OK.
>>From a root task, we wait when all task have passed the forking stage
> and then enumirate all namespaces and mark them as populated.
>>
>> (more comments inline)
>>
>>> https://jira.sw.ru/browse/PSBM-48222
>>>
>>> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
>>> ---
>>> criu/cr-restore.c | 7 ++++---
>>> criu/include/namespaces.h | 2 +-
>>> criu/mount.c | 14 ++++++--------
>>> criu/namespaces.c | 4 ++--
>>> 4 files changed, 13 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
>>> index 1e3d823..5511447 100644
>>> --- a/criu/cr-restore.c
>>> +++ b/criu/cr-restore.c
>>> @@ -1309,16 +1309,17 @@ static int restore_task_with_children(void *_arg)
>>>
>>> restore_pgid();
>>>
>>> - if (restore_finish_stage(CR_STATE_FORKING) < 0)
>>> - goto err;
>>> -
>>> if (current->parent == NULL) {
>>> + futex_wait_while_gt(&task_entries->nr_in_progress, 1);
>>
>> Why is it needed here?
>
> Wait when all tasks have passed the forking stage.
We have a helper for it, don't we?
Also I'd appreciate a comment here saying why we need to wait.
>>
>>> if (depopulate_roots_yard())
>>> goto err;
>>>
>>> fini_restore_mntns();
>>> }
>>>
>>> + if (restore_finish_stage(CR_STATE_FORKING) < 0)
>>> + goto err;
>>> +
>>> if (restore_one_task(current->pid.virt, ca->core))
>>> goto err;
>>>
More information about the CRIU
mailing list