From de71bc69170cfeceb24bddd431ad10b8ea607d42 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Fri, 31 May 2013 19:01:31 +0400 Subject: [PATCH] restore: add action scripts setup-namespaces (v2) 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 Signed-off-by: Pavel Emelyanov --- 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 70c5e6844..8983f4cff 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); + 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); + 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 caee41d32..a5c0667e3 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,