[07/11] restore: add a function to wait when other tasks finish a stage

Submitted by Andrei Vagin on Feb. 2, 2017, 12:04 a.m.

Details

Message ID 1485993871-3990-8-git-send-email-avagin@openvz.org
State New
Series "Dump and restore nested network namespaces"
Headers show

Commit Message

Andrei Vagin Feb. 2, 2017, 12:04 a.m.
From: Andrei Vagin <avagin@virtuozzo.com>

It is used now to close descriptors of mount namespaces
and will be used for network namespaces too.

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/cr-restore.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index ba8ee57..681655d 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -119,6 +119,7 @@  static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
 static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
 static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
 
+static void restore_wait_other_tasks();
 
 static int crtools_prepare_shared(void)
 {
@@ -1474,7 +1475,7 @@  static int restore_task_with_children(void *_arg)
 		 * Wait when all tasks passed the CR_STATE_FORKING stage.
 		 * It means that all tasks entered into their namespaces.
 		 */
-		futex_wait_while_gt(&task_entries->nr_in_progress, 1);
+		restore_wait_other_tasks();
 
 		fini_restore_mntns();
 	}
@@ -1518,6 +1519,19 @@  static inline int stage_participants(int next_stage)
 	return -1;
 }
 
+static inline int stage_current_participants(int next_stage)
+{
+	switch (next_stage) {
+	case CR_STATE_FORKING:
+		return 1;
+	case CR_STATE_RESTORE:
+		return current->nr_threads;
+	}
+
+	BUG();
+	return -1;
+}
+
 static int restore_wait_inprogress_tasks()
 {
 	int ret;
@@ -1546,6 +1560,18 @@  static int restore_switch_stage(int next_stage)
 	return restore_wait_inprogress_tasks();
 }
 
+/* Wait all tasks except the current one */
+static void restore_wait_other_tasks()
+{
+	int participants, stage;
+
+	stage = futex_get(&task_entries->start);
+	participants = stage_current_participants(stage);
+
+	futex_wait_while_gt(&task_entries->nr_in_progress,
+				participants);
+}
+
 static int attach_to_tasks(bool root_seized)
 {
 	struct pstree_item *item;

Comments

Pavel Emelianov Feb. 8, 2017, 9:51 a.m.
On 02/02/2017 03:04 AM, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@virtuozzo.com>
> 
> It is used now to close descriptors of mount namespaces
> and will be used for network namespaces too.
> 
> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
> ---
>  criu/cr-restore.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> index ba8ee57..681655d 100644
> --- a/criu/cr-restore.c
> +++ b/criu/cr-restore.c
> @@ -119,6 +119,7 @@ static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
>  static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
>  static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
>  
> +static void restore_wait_other_tasks();
>  
>  static int crtools_prepare_shared(void)
>  {
> @@ -1474,7 +1475,7 @@ static int restore_task_with_children(void *_arg)
>  		 * Wait when all tasks passed the CR_STATE_FORKING stage.
>  		 * It means that all tasks entered into their namespaces.
>  		 */
> -		futex_wait_while_gt(&task_entries->nr_in_progress, 1);
> +		restore_wait_other_tasks();
>  
>  		fini_restore_mntns();
>  	}
> @@ -1518,6 +1519,19 @@ static inline int stage_participants(int next_stage)
>  	return -1;
>  }
>  
> +static inline int stage_current_participants(int next_stage)
> +{
> +	switch (next_stage) {
> +	case CR_STATE_FORKING:
> +		return 1;

Waiting for nr_in_progress to become 1 (or less) makes sense, but ...

> +	case CR_STATE_RESTORE:
> +		return current->nr_threads;

Why this???

> +	}
> +
> +	BUG();
> +	return -1;
> +}
> +
>  static int restore_wait_inprogress_tasks()
>  {
>  	int ret;
> @@ -1546,6 +1560,18 @@ static int restore_switch_stage(int next_stage)
>  	return restore_wait_inprogress_tasks();
>  }
>  
> +/* Wait all tasks except the current one */
> +static void restore_wait_other_tasks()
> +{
> +	int participants, stage;
> +
> +	stage = futex_get(&task_entries->start);
> +	participants = stage_current_participants(stage);
> +
> +	futex_wait_while_gt(&task_entries->nr_in_progress,
> +				participants);
> +}
> +
>  static int attach_to_tasks(bool root_seized)
>  {
>  	struct pstree_item *item;
>
Andrey Vagin Feb. 9, 2017, 1:03 a.m.
On Wed, Feb 08, 2017 at 12:51:05PM +0300, Pavel Emelyanov wrote:
> On 02/02/2017 03:04 AM, Andrei Vagin wrote:
> > From: Andrei Vagin <avagin@virtuozzo.com>
> > 
> > It is used now to close descriptors of mount namespaces
> > and will be used for network namespaces too.
> > 
> > Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
> > ---
> >  criu/cr-restore.c | 28 +++++++++++++++++++++++++++-
> >  1 file changed, 27 insertions(+), 1 deletion(-)
> > 
> > diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> > index ba8ee57..681655d 100644
> > --- a/criu/cr-restore.c
> > +++ b/criu/cr-restore.c
> > @@ -119,6 +119,7 @@ static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
> >  static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
> >  static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
> >  
> > +static void restore_wait_other_tasks();
> >  
> >  static int crtools_prepare_shared(void)
> >  {
> > @@ -1474,7 +1475,7 @@ static int restore_task_with_children(void *_arg)
> >  		 * Wait when all tasks passed the CR_STATE_FORKING stage.
> >  		 * It means that all tasks entered into their namespaces.
> >  		 */
> > -		futex_wait_while_gt(&task_entries->nr_in_progress, 1);
> > +		restore_wait_other_tasks();
> >  
> >  		fini_restore_mntns();
> >  	}
> > @@ -1518,6 +1519,19 @@ static inline int stage_participants(int next_stage)
> >  	return -1;
> >  }
> >  
> > +static inline int stage_current_participants(int next_stage)
> > +{
> > +	switch (next_stage) {
> > +	case CR_STATE_FORKING:
> > +		return 1;
> 
> Waiting for nr_in_progress to become 1 (or less) makes sense, but ...
> 
> > +	case CR_STATE_RESTORE:
> > +		return current->nr_threads;
> 
> Why this???

Wait all tasks except the current one. Threads are created on this stage
and each thread has to report at the end of this stage.
> 
> > +	}
> > +
> > +	BUG();
> > +	return -1;
> > +}
> > +
> >  static int restore_wait_inprogress_tasks()
> >  {
> >  	int ret;
> > @@ -1546,6 +1560,18 @@ static int restore_switch_stage(int next_stage)
> >  	return restore_wait_inprogress_tasks();
> >  }
> >  
> > +/* Wait all tasks except the current one */
> > +static void restore_wait_other_tasks()
> > +{
> > +	int participants, stage;
> > +
> > +	stage = futex_get(&task_entries->start);
> > +	participants = stage_current_participants(stage);
> > +
> > +	futex_wait_while_gt(&task_entries->nr_in_progress,
> > +				participants);
> > +}
> > +
> >  static int attach_to_tasks(bool root_seized)
> >  {
> >  	struct pstree_item *item;
> > 
>
Pavel Emelianov Feb. 10, 2017, 12:21 p.m.
On 02/09/2017 04:03 AM, Andrei Vagin wrote:
> On Wed, Feb 08, 2017 at 12:51:05PM +0300, Pavel Emelyanov wrote:
>> On 02/02/2017 03:04 AM, Andrei Vagin wrote:
>>> From: Andrei Vagin <avagin@virtuozzo.com>
>>>
>>> It is used now to close descriptors of mount namespaces
>>> and will be used for network namespaces too.
>>>
>>> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
>>> ---
>>>  criu/cr-restore.c | 28 +++++++++++++++++++++++++++-
>>>  1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
>>> index ba8ee57..681655d 100644
>>> --- a/criu/cr-restore.c
>>> +++ b/criu/cr-restore.c
>>> @@ -119,6 +119,7 @@ static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core)
>>>  static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
>>>  static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
>>>  
>>> +static void restore_wait_other_tasks();
>>>  
>>>  static int crtools_prepare_shared(void)
>>>  {
>>> @@ -1474,7 +1475,7 @@ static int restore_task_with_children(void *_arg)
>>>  		 * Wait when all tasks passed the CR_STATE_FORKING stage.
>>>  		 * It means that all tasks entered into their namespaces.
>>>  		 */
>>> -		futex_wait_while_gt(&task_entries->nr_in_progress, 1);
>>> +		restore_wait_other_tasks();
>>>  
>>>  		fini_restore_mntns();
>>>  	}
>>> @@ -1518,6 +1519,19 @@ static inline int stage_participants(int next_stage)
>>>  	return -1;
>>>  }
>>>  
>>> +static inline int stage_current_participants(int next_stage)
>>> +{
>>> +	switch (next_stage) {
>>> +	case CR_STATE_FORKING:
>>> +		return 1;
>>
>> Waiting for nr_in_progress to become 1 (or less) makes sense, but ...
>>
>>> +	case CR_STATE_RESTORE:
>>> +		return current->nr_threads;
>>
>> Why this???
> 
> Wait all tasks except the current one. Threads are created on this stage
> and each thread has to report at the end of this stage.

I don't get this explanation :( nr_threads account for threads across all
tasks, not only the current one.

>>
>>> +	}
>>> +
>>> +	BUG();
>>> +	return -1;
>>> +}
>>> +
>>>  static int restore_wait_inprogress_tasks()
>>>  {
>>>  	int ret;
>>> @@ -1546,6 +1560,18 @@ static int restore_switch_stage(int next_stage)
>>>  	return restore_wait_inprogress_tasks();
>>>  }
>>>  
>>> +/* Wait all tasks except the current one */
>>> +static void restore_wait_other_tasks()
>>> +{
>>> +	int participants, stage;
>>> +
>>> +	stage = futex_get(&task_entries->start);
>>> +	participants = stage_current_participants(stage);
>>> +
>>> +	futex_wait_while_gt(&task_entries->nr_in_progress,
>>> +				participants);
>>> +}
>>> +
>>>  static int attach_to_tasks(bool root_seized)
>>>  {
>>>  	struct pstree_item *item;
>>>
>>
> .
>