From 2d56d1b0560698827d40e8eb16cc20a3571081e4 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 2 Aug 2012 07:55:05 +0400 Subject: [PATCH] ns: Add ability to save original ns and restoring it back while switcing This will be required for parasite transport socket creation -- it will have to be created in a net ns we're putting parasite in and then we'll have to restore it back to original to go on dumping. Signed-off-by: Pavel Emelyanov --- include/namespaces.h | 3 ++- ipc_ns.c | 2 +- namespaces.c | 37 +++++++++++++++++++++++++++++++++---- uts_ns.c | 2 +- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/namespaces.h b/include/namespaces.h index eed805c7a..244107ca6 100644 --- a/include/namespaces.h +++ b/include/namespaces.h @@ -7,5 +7,6 @@ int dump_namespaces(struct pid *pid, unsigned int ns_flags); int prepare_namespace(int pid, unsigned long clone_flags); struct cr_options; int try_show_namespaces(int pid, struct cr_options *); -int switch_ns(int pid, int type, char *ns); +int switch_ns(int pid, int type, char *ns, int *rst); +int restore_ns(int rst, int type); #endif diff --git a/ipc_ns.c b/ipc_ns.c index f35852c99..390ac8048 100644 --- a/ipc_ns.c +++ b/ipc_ns.c @@ -456,7 +456,7 @@ int dump_ipc_ns(int ns_pid, const struct cr_fdset *fdset) { int ret; - ret = switch_ns(ns_pid, CLONE_NEWIPC, "ipc"); + ret = switch_ns(ns_pid, CLONE_NEWIPC, "ipc", NULL); if (ret < 0) return ret; diff --git a/namespaces.c b/namespaces.c index 9e3644193..ee6c59a10 100644 --- a/namespaces.c +++ b/namespaces.c @@ -9,7 +9,7 @@ #include "mount.h" #include "namespaces.h" -int switch_ns(int pid, int type, char *ns) +int switch_ns(int pid, int type, char *ns, int *rst) { char buf[32]; int nsfd; @@ -19,15 +19,44 @@ int switch_ns(int pid, int type, char *ns) nsfd = open(buf, O_RDONLY); if (nsfd < 0) { pr_perror("Can't open ipcns file"); - goto out; + goto err_ns; + } + + if (rst) { + snprintf(buf, sizeof(buf), "/proc/self/ns/%s", ns); + *rst = open(buf, O_RDONLY); + if (*rst < 0) { + pr_perror("Can't open ns file"); + goto err_rst; + } } ret = setns(nsfd, type); - if (ret < 0) + if (ret < 0) { pr_perror("Can't setns %d/%s", pid, ns); + goto err_set; + } close(nsfd); -out: + return 0; + +err_set: + if (rst) + close(*rst); +err_rst: + close(nsfd); +err_ns: + return -1; +} + +int restore_ns(int rst, int type) +{ + int ret; + + ret = setns(rst, type); + if (ret < 0) + pr_perror("Can't restore ns back"); + return ret; } diff --git a/uts_ns.c b/uts_ns.c index b6541bc37..c4ddf4072 100644 --- a/uts_ns.c +++ b/uts_ns.c @@ -18,7 +18,7 @@ int dump_uts_ns(int ns_pid, struct cr_fdset *fdset) struct utsname ubuf; UtsnsEntry ue = UTSNS_ENTRY__INIT; - ret = switch_ns(ns_pid, CLONE_NEWUTS, "uts"); + ret = switch_ns(ns_pid, CLONE_NEWUTS, "uts", NULL); if (ret < 0) return ret;