[CRIU] [PATCH] add join-ns opt to criu restore
Pavel Emelyanov
xemul at virtuozzo.com
Tue Mar 15 07:55:33 PDT 2016
On 03/15/2016 09:08 AM, Dengguangxing wrote:
>
> join-ns will restore process with specified existing namespace.
> This opt can be used in this fomat:
> --join-ns NS:PID, for example net:12345.
>
> pid namespaces is not supported yet. As fork() is needed to make
> new pid-namespace take effect. That makes it hard for criu to track the
> child-process through pid because another child process has been
> created after fork().
Thanks for the great work :)
btw, this fixes issue #109 on github, doesn't it?
Please, find my comments inline.
> Signed-off-by: Deng Guangxing <dengguangxing at huawei.com>
> ---
> criu/cr-restore.c | 5 +++
> criu/crtools.c | 44 ++++++++++++++++++++++++-
> criu/include/cr_options.h | 1 +
> criu/include/namespaces.h | 10 ++++++
> criu/namespaces.c | 82 ++++++++++++++++++++++++++++++++++++++++-------
> 5 files changed, 129 insertions(+), 13 deletions(-)
>
> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> index 30ddff9..e3f0add 100644
> --- a/criu/cr-restore.c
> +++ b/criu/cr-restore.c
> @@ -1566,6 +1566,11 @@ static int restore_task_with_children(void *_arg)
>
> /* Restore root task */
> if (current->parent == NULL) {
> + if (join_namespaces()) {
There are three things to sort out:
1. What if root task lives in netns, but we ask for --join-ns net?
2. What if we pass --unshare net and --join-ns net?
3. What if we pass --empty-ns net and --join-ns net?
> + pr_perror("Join namespaces failed");
> + goto err;
> + }
> +
> if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
> goto err;
>
> @@ -234,6 +269,7 @@ int main(int argc, char *argv[], char *envp[])
> { "work-dir", required_argument, 0, 'W' },
> { "log-file", required_argument, 0, 'o' },
> { "namespaces", required_argument, 0, 'n' },
> + { "join-ns", required_argument, 0, 'J' },
Please, also fix the images/rpc.proto and criu/cr-service.c to support this option
in RPC API.
> { "root", required_argument, 0, 'r' },
> { USK_EXT_PARAM, optional_argument, 0, 'x' },
> { "help", no_argument, 0, 'h' },
> @@ -73,28 +106,41 @@ bool check_ns_proc(struct fd_link *link)
> int switch_ns(int pid, struct ns_desc *nd, int *rst)
> {
> char buf[32];
> - int nsfd;
> + int nsfd, self_fd;
> int ret = -1;
> + struct stat st, self_st;
>
> nsfd = open_proc(pid, "ns/%s", nd->str);
> if (nsfd < 0) {
> - pr_perror("Can't open ipcns file");
> + pr_perror("Can't open ns file");
> + goto err_ns;
> + }
> + if (fstat(nsfd, &st) == -1) {
> + pr_perror("Can't get ns file stat");
> goto err_ns;
> }
>
> + snprintf(buf, sizeof(buf), "/proc/self/ns/%s", nd->str);
> + self_fd = open(buf, O_RDONLY);
> + if (self_fd < 0) {
> + pr_perror("Can't open ns file");
> + goto err_rst;
> + }
> + if (fstat(self_fd, &self_st) == -1) {
> + pr_perror("Can't get ns file stat");
> + goto err_ns;
> + }
> if (rst) {
> - snprintf(buf, sizeof(buf), "/proc/self/ns/%s", nd->str);
> - *rst = open(buf, O_RDONLY);
> - if (*rst < 0) {
> - pr_perror("Can't open ns file");
> - goto err_rst;
> - }
> + *rst = self_fd;
> }
>
> - ret = setns(nsfd, nd->cflag);
> - if (ret < 0) {
> - pr_perror("Can't setns %d/%s", pid, nd->str);
> - goto err_set;
> + //re-set the same user-ns would fail, check it here
> + if (st.st_ino != self_st.st_ino) {
> + ret = setns(nsfd, nd->cflag);
> + if (ret < 0) {
> + pr_perror("Can't setns %d/%s", pid, nd->str);
> + goto err_set;
> + }
Please describe the change in switch_ns(), it's unclear what you're
trying to achieve here.
> }
>
> close(nsfd);
-- Pavel
More information about the CRIU
mailing list