[CRIU] [PATCH] ns: Implement setns_from_fdstore() for repeating code
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Jul 11 12:47:37 MSK 2017
Introduce a helper and use it instead of repeating code.
Use file and line of caller in error message printing
to allow the caller do not use additional print.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-restore.c | 31 ++++---------------------------
criu/include/namespaces.h | 5 +++++
criu/mount.c | 23 +----------------------
criu/namespaces.c | 40 ++++++++++++++++++++++++++++------------
criu/net.c | 28 ++++------------------------
criu/sockets.c | 12 +++---------
6 files changed, 45 insertions(+), 94 deletions(-)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e14fa0694..a9dacce8f 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -431,8 +431,6 @@ static void wait_pid_ns_helper_prepared(struct ns_id *pid_ns, struct pid *pid)
static int set_pid_for_children_ns(struct ns_id *pid_ns)
{
- int fd, ret = 0;
-
if (!(root_ns_mask & CLONE_NEWPID))
return 0;
@@ -441,21 +439,11 @@ static int set_pid_for_children_ns(struct ns_id *pid_ns)
if (current->pid_for_children_ns == pid_ns)
return 0;
- fd = fdstore_get(pid_ns->pid.nsfd_id);
- if (fd < 0) {
- pr_err("Can't get pid_ns fd\n");
+ if (setns_from_fdstore(pid_ns->pid.nsfd_id, CLONE_NEWPID) < 0)
return -1;
- }
- if (setns(fd, CLONE_NEWPID) < 0) {
- pr_perror("Can't set pid ns");
- ret = -1;
- } else {
- current->pid_for_children_ns = pid_ns;
- }
-
- close(fd);
- return ret;
+ current->pid_for_children_ns = pid_ns;
+ return 0;
}
static int restore_task_pfc_before_user_ns(void)
@@ -1310,7 +1298,6 @@ static int call_clone_fn(void *arg)
struct cr_clone_arg *ca = arg;
struct ns_id *pid_ns;
pid_t pid;
- int fd;
pid_ns = lookup_ns_by_id(ca->item->ids->pid_ns_id, &pid_ns_desc);
BUG_ON(!pid_ns);
@@ -1320,18 +1307,8 @@ static int call_clone_fn(void *arg)
return -1;
}
- fd = fdstore_get(pid_ns->user_ns->user.nsfd_id);
- if (fd < 0) {
- pr_err("Can't get ns fd\n");
+ if (setns_from_fdstore(pid_ns->user_ns->user.nsfd_id, CLONE_NEWUSER))
return -1;
- }
-
- if (setns(fd, CLONE_NEWUSER) < 0) {
- pr_perror("Can't set user ns");
- close(fd);
- return -1;
- }
- close(fd);
close_pid_proc();
pid = clone_noasan(restore_task_with_children, ca->clone_flags | CLONE_PARENT | SIGCHLD, ca);
diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
index 44520a81a..bc7372c22 100644
--- a/criu/include/namespaces.h
+++ b/criu/include/namespaces.h
@@ -264,6 +264,11 @@ extern int __userns_call(const char *func_name, uns_call_t call, int flags,
__userns_call(__stringify(__call), __call, __flags, \
__arg, __arg_size, __fd)
+extern int __setns_from_fdstore(int fd_id, int nstype, const char *, int);
+
+#define setns_from_fdstore(fd_id, nstype) \
+ __setns_from_fdstore(fd_id, nstype, __FILE__, __LINE__)
+
extern int add_ns_shared_cb(int (*actor)(void *data), void *data);
extern struct ns_id *get_socket_ns(int lfd);
diff --git a/criu/mount.c b/criu/mount.c
index 83915b7b2..b825b7086 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -2713,24 +2713,6 @@ int mntns_maybe_create_roots(void)
return create_mnt_roots();
}
-static int do_restore_task_mnt_ns(struct ns_id *nsid, struct pstree_item *current)
-{
- int fd;
-
- fd = fdstore_get(nsid->mnt.nsfd_id);
- if (fd < 0)
- return -1;
-
- if (setns(fd, CLONE_NEWNS)) {
- pr_perror("Can't restore mntns");
- close(fd);
- return -1;
- }
- close(fd);
-
- return 0;
-}
-
int restore_task_mnt_ns(struct pstree_item *current)
{
unsigned int id = current->ids->mnt_ns_id;
@@ -2758,10 +2740,7 @@ int restore_task_mnt_ns(struct pstree_item *current)
BUG_ON(nsid->type == NS_CRIU);
- if (do_restore_task_mnt_ns(nsid, current))
- return -1;
-
- return 0;
+ return setns_from_fdstore(nsid->mnt.nsfd_id, CLONE_NEWNS);
}
void fini_restore_mntns(void)
diff --git a/criu/namespaces.c b/criu/namespaces.c
index 100a631e9..127a202d6 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -2553,26 +2553,16 @@ int prepare_namespace_before_tasks(void)
int __set_user_ns(struct ns_id *ns)
{
- int fd;
-
if (!(root_ns_mask & CLONE_NEWUSER))
return 0;
if (current->user_ns && current->user_ns->id == ns->id)
return 0;
- fd = fdstore_get(ns->user.nsfd_id);
- if (fd < 0) {
- pr_err("Can't get ns fd\n");
+ if (setns_from_fdstore(ns->user.nsfd_id, CLONE_NEWUSER))
return -1;
- }
- if (setns(fd, CLONE_NEWUSER) < 0) {
- pr_perror("Can't setns");
- close(fd);
- return -1;
- }
+
current->user_ns = ns;
- close(fd);
if (prepare_userns_creds() < 0) {
pr_err("Can't set creds\n");
@@ -2834,5 +2824,31 @@ int destroy_pid_ns_helpers(void)
return 0;
}
+int __setns_from_fdstore(int fd_id, int nstype, const char *file, int line)
+{
+ int fd, saved_errno, ret;
+
+ fd = fdstore_get(fd_id);
+ if (fd < 0)
+ goto err;
+
+ ret = setns(fd, nstype);
+ saved_errno = errno;
+ close(fd);
+ if (ret) {
+ errno = saved_errno;
+ pr_perror("Can't set user ns");
+ goto err;
+ }
+
+ return 0;
+err:
+ pr_err("Can't set %s_ns from fdstore (called from %s: %d)\n",
+ ns_to_string(nstype), file, line);
+ return -1;
+}
+
+
+
struct ns_desc pid_ns_desc = NS_DESC_ENTRY(CLONE_NEWPID, "pid", "pid_for_children");
struct ns_desc user_ns_desc = NS_DESC_ENTRY(CLONE_NEWUSER, "user", NULL);
diff --git a/criu/net.c b/criu/net.c
index 15aae2be4..99a78ee14 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -2060,23 +2060,16 @@ static int do_create_net_ns(struct ns_id *ns)
static int create_net_ns(void *arg)
{
struct ns_id *uns, *ns = arg;
- int ufd, ret;
+ int ret;
uns = ns->user_ns;
- ufd = fdstore_get(uns->user.nsfd_id);
- if (ufd < 0) {
- pr_err("Can't get user ns\n");
+ if (setns_from_fdstore(uns->user.nsfd_id, CLONE_NEWUSER))
exit(1);
- }
- if (setns(ufd, CLONE_NEWUSER) < 0) {
- pr_perror("Can't set user ns");
- exit(2);
- }
+
if (prepare_userns_creds() < 0) {
pr_err("Can't prepare creds\n");
exit(3);
}
- close(ufd);
ret = do_create_net_ns(ns) ? 3 : 0;
exit(ret);
}
@@ -2160,23 +2153,10 @@ int prepare_net_namespaces(void)
static int do_restore_task_net_ns(struct ns_id *nsid, struct pstree_item *current)
{
- int fd;
-
if (!(root_ns_mask & CLONE_NEWNET))
return 0;
- fd = fdstore_get(nsid->net.nsfd_id);
- if (fd < 0)
- return -1;
-
- if (setns(fd, CLONE_NEWNET)) {
- pr_perror("Can't restore netns");
- close(fd);
- return -1;
- }
- close(fd);
-
- return 0;
+ return setns_from_fdstore(nsid->net.nsfd_id, CLONE_NEWNET);
}
int restore_task_net_ns(struct pstree_item *current)
diff --git a/criu/sockets.c b/criu/sockets.c
index 9b0c4df99..fd6f525a0 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -750,7 +750,6 @@ static uint32_t last_ns_id = 0;
int set_netns(uint32_t ns_id)
{
struct ns_id *ns;
- int nsfd;
if (!(root_ns_mask & CLONE_NEWNET))
return 0;
@@ -763,16 +762,11 @@ int set_netns(uint32_t ns_id)
pr_err("Unable to find a network namespace\n");
return -1;
}
- nsfd = fdstore_get(ns->net.nsfd_id);
- if (nsfd < 0)
- return -1;
- if (setns(nsfd, CLONE_NEWNET)) {
- pr_perror("Unable to switch a network namespace");
- close(nsfd);
+
+ if (setns_from_fdstore(ns->net.nsfd_id, CLONE_NEWNET))
return -1;
- }
+
last_ns_id = ns_id;
- close(nsfd);
close_pid_proc();
More information about the CRIU
mailing list