From eea63587e692fa1dc44c2d96c0a53788835fac7d Mon Sep 17 00:00:00 2001 From: Liu Hua Date: Thu, 2 Sep 2021 11:10:41 +0800 Subject: [PATCH] namespaces: add helpers to switch/restore mnt ns When restoring mnt, we should restore current work directory. Signed-off-by: Liu Hua --- criu/include/namespaces.h | 2 ++ criu/namespaces.c | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h index ddf0dbabb..034605917 100644 --- a/criu/include/namespaces.h +++ b/criu/include/namespaces.h @@ -165,8 +165,10 @@ extern int prepare_namespace(struct pstree_item *item, unsigned long clone_flags extern int prepare_userns_creds(void); extern int switch_ns(int pid, struct ns_desc *nd, int *rst); +extern int switch_mnt_ns(int pid, int *rst, int *cwd_fd); extern int switch_ns_by_fd(int nsfd, struct ns_desc *nd, int *rst); extern int restore_ns(int rst, struct ns_desc *nd); +extern int restore_mnt_ns(int rst, int *cwd_fd); extern int dump_task_ns_ids(struct pstree_item *); extern int predump_task_ns_ids(struct pstree_item *); diff --git a/criu/namespaces.c b/criu/namespaces.c index 92e0ed31a..7fa58682b 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -282,6 +282,51 @@ int restore_ns(int rst, struct ns_desc *nd) return ret; } +int switch_mnt_ns(int pid, int *rst, int *cwd_fd) +{ + int ret; + int fd; + + if (!cwd_fd) + return switch_ns(pid, &mnt_ns_desc, rst); + + fd = open(".", O_PATH); + if (fd < 0) { + pr_perror("unable to open current directory"); + return fd; + } + + ret = switch_ns(pid, &mnt_ns_desc, rst); + if (ret < 0) { + close(fd); + return ret; + } + + *cwd_fd = fd; + return 0; +} + +int restore_mnt_ns(int rst, int *cwd_fd) +{ + int ret = -1; + + ret = restore_ns(rst, &mnt_ns_desc); + if (ret < 0) + goto err_restore; + + if (cwd_fd) { + ret = fchdir(*cwd_fd); + if (ret) + pr_perror("unable to restore current directory"); + } + +err_restore: + if (cwd_fd) + close_safe(cwd_fd); + + return ret; +} + struct ns_id *ns_ids = NULL; static unsigned int ns_next_id = 1; unsigned long root_ns_mask = 0;