[CRIU] [PATCH] restore: add action scripts setup-namespaces (v2)
Pavel Emelyanov
xemul at parallels.com
Fri May 31 08:37:55 EDT 2013
On 05/31/2013 02:29 PM, Andrey Vagin wrote:
> After creating namespaces we may need to apply some configuration.
> For example uid and gid maps should be applied in this moment.
>
> This script should be executed from crtools, but namespaces are created
> in a root process, so we need to add a new stage for synchronizing.
>
> v2: use a separate stage instead of socketpair.
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> cr-restore.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
> include/restorer.h | 1 +
> 2 files changed, 43 insertions(+), 4 deletions(-)
>
> diff --git a/cr-restore.c b/cr-restore.c
> index 70c5e68..8983f4c 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -931,6 +931,14 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
>
> exit = (siginfo->si_code == CLD_EXITED);
> status = siginfo->si_status;
> +
> + /* skip scripts */
> + if (!current && root_item->pid.real != pid) {
> + pid = waitpid(root_item->pid.real, &status, WNOHANG);
Shouldn't while () loop be here?
> + if (pid <= 0)
> + return;
> + }
> +
> if (!current || status)
> goto err;
>
> @@ -1091,6 +1099,8 @@ static int restore_task_with_children(void *_arg)
> if (mount_proc())
> exit(1);
>
> + restore_finish_stage(CR_STATE_RESTORE_NS);
> +
> if (root_prepare_shared())
> exit(1);
> }
> @@ -1158,6 +1168,8 @@ static int restore_task_with_children(void *_arg)
> static inline int stage_participants(int next_stage)
> {
> switch (next_stage) {
> + case CR_STATE_RESTORE_NS:
> + return 1;
> case CR_STATE_FORKING:
> return task_entries->nr_tasks + task_entries->nr_helpers;
> case CR_STATE_RESTORE_PGID:
> @@ -1173,7 +1185,7 @@ static inline int stage_participants(int next_stage)
> return -1;
> }
>
> -static int restore_switch_stage(int next_stage)
> +static int restore_wait_inprogress_tasks()
> {
> int ret;
> futex_t *np = &task_entries->nr_in_progress;
> @@ -1183,7 +1195,19 @@ static int restore_switch_stage(int next_stage)
> if (ret < 0)
> return ret;
>
> - futex_set(np, stage_participants(next_stage));
> + return 0;
> +}
> +
> +static int restore_switch_stage(int next_stage)
> +{
> + int ret;
> +
> + ret = restore_wait_inprogress_tasks();
> + if (ret)
> + return ret;
> +
> + futex_set(&task_entries->nr_in_progress,
> + stage_participants(next_stage));
> futex_set_and_wake(&task_entries->start, next_stage);
> return 0;
> }
> @@ -1230,12 +1254,26 @@ static int restore_root_task(struct pstree_item *init)
> return -1;
> }
>
> - futex_set(&task_entries->nr_in_progress, stage_participants(CR_STATE_FORKING));
> + futex_set(&task_entries->nr_in_progress,
> + stage_participants(CR_STATE_RESTORE_NS));
>
> ret = fork_with_pid(init);
> if (ret < 0)
> return -1;
>
> + pr_info("Wait until namespaces are created\n");
> + ret = restore_wait_inprogress_tasks();
> + if (ret)
> + goto out;
> +
> + ret = run_scripts("setup-namespaces");
> + if (ret)
> + goto out;
> +
> + ret = restore_switch_stage(CR_STATE_FORKING);
This will call "wait-inprogress" again. Can we tune this thing out?
> + if (ret < 0)
> + goto out;
> +
> pr_info("Wait until all tasks are forked\n");
> ret = restore_switch_stage(CR_STATE_RESTORE_PGID);
> if (ret < 0)
> @@ -1303,7 +1341,7 @@ static int prepare_task_entries()
> task_entries->nr_threads = 0;
> task_entries->nr_tasks = 0;
> task_entries->nr_helpers = 0;
> - futex_set(&task_entries->start, CR_STATE_FORKING);
> + futex_set(&task_entries->start, CR_STATE_RESTORE_NS);
> mutex_init(&task_entries->zombie_lock);
>
> return 0;
> diff --git a/include/restorer.h b/include/restorer.h
> index caee41d..a5c0667 100644
> --- a/include/restorer.h
> +++ b/include/restorer.h
> @@ -162,6 +162,7 @@ struct shmems {
> #define TASK_ENTRIES_SIZE 4096
>
> enum {
> + CR_STATE_RESTORE_NS, /* is used for executing "setup-namespace" scripts */
> CR_STATE_FORKING,
> CR_STATE_RESTORE_PGID,
> CR_STATE_RESTORE,
>
More information about the CRIU
mailing list