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;