[CRIU] [PATCH 1/3] ns: Remember procfs NS entries for root task
Cyrill Gorcunov
gorcunov at openvz.org
Mon Apr 29 12:19:57 EDT 2013
This will allow us to restore paths as /proc/self/ns/net
if there was not unshare call done in the dumpee (which
is a different case).
Thus we simply collect procfs NS names and inode numbers
for future use.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
cr-dump.c | 9 ++++++++
include/namespaces.h | 25 +++++++++++++++++++++
namespaces.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+)
diff --git a/cr-dump.c b/cr-dump.c
index 5743551..db404ef 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1559,6 +1559,15 @@ int cr_dump_tasks(pid_t pid, const struct cr_options *opts)
if (cpu_init())
goto err;
+ /*
+ * On dump procedure if we've been requested to dump
+ * namespaces -- parse inode numbers associated in
+ * procfs thus we could try to restore files opened
+ * with NS entries.
+ */
+ if (ns_proc_entries_init(pid))
+ goto err;
+
if (write_img_inventory())
goto err;
diff --git a/include/namespaces.h b/include/namespaces.h
index c0a1ff7..f77f751 100644
--- a/include/namespaces.h
+++ b/include/namespaces.h
@@ -23,4 +23,29 @@ int dump_task_ns_ids(struct pstree_item *);
extern unsigned long current_ns_mask;
+enum {
+ PROC_NS_NET,
+ PROC_NS_UTS,
+ PROC_NS_IPC,
+ PROC_NS_PID,
+ PROC_NS_USER,
+ PROC_NS_MNT,
+
+ PROC_NS_MAX
+};
+
+struct ns_proc_entry {
+ char *name;
+ size_t name_len;
+ unsigned long i_ino;
+};
+
+#define NS_PROC_ENTRY(_index, _name) \
+ [_index] = { \
+ .name = _name, \
+ .name_len = sizeof(_name) - 1, \
+ }
+
+extern int ns_proc_entries_init(pid_t pid);
+
#endif /* __CR_NS_H__ */
diff --git a/namespaces.c b/namespaces.c
index 1e13077..6148166 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -10,6 +10,67 @@
#include "namespaces.h"
#include "net.h"
+static struct ns_proc_entry ns_proc_entries[PROC_NS_MAX] = {
+ NS_PROC_ENTRY(PROC_NS_NET, "net"),
+ NS_PROC_ENTRY(PROC_NS_UTS, "uts"),
+ NS_PROC_ENTRY(PROC_NS_IPC, "ipc"),
+ NS_PROC_ENTRY(PROC_NS_PID, "pid"),
+ NS_PROC_ENTRY(PROC_NS_USER, "user"),
+ NS_PROC_ENTRY(PROC_NS_MNT, "mnt"),
+};
+
+int ns_proc_entries_init(pid_t pid)
+{
+ int nsfd, ret = 0;
+ unsigned int i;
+ int fd = -1;
+ char buf[64];
+
+ nsfd = open_proc(pid, "ns");
+ if (nsfd < 0) {
+ pr_perror("Can't open ns proc entry");
+ return -1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(ns_proc_entries); i++) {
+ size_t sz = ns_proc_entries[i].name_len;
+ char *end = NULL;
+
+ ret = openat(nsfd, ns_proc_entries[i].name, O_RDONLY);
+ if (ret < 0) {
+ if (errno != ENOENT) {
+ pr_perror("Can't open ns proc %s entry",
+ ns_proc_entries[i].name);
+ break;
+ } else
+ continue;
+ }
+ fd = ret;
+
+ ret = -1;
+ if (read_fd_link(fd, buf, sizeof(buf))) {
+ pr_err("Can't read ns proc link %s\n",
+ ns_proc_entries[i].name);
+ break;
+ }
+
+ /*
+ * We expect `%s:[%lu]' format here.
+ */
+ ns_proc_entries[i].i_ino = strtoul(&buf[sz + 2], &end, 10);
+ if (!end || *end != ']') {
+ pr_err("Failed parsing ns proc %s %s\n",
+ ns_proc_entries[i].name, end);
+ break;
+ }
+ ret = 0;
+ }
+
+ close_safe(&fd);
+ close(nsfd);
+ return ret;
+}
+
int switch_ns(int pid, struct ns_desc *nd, int *rst)
{
char buf[32];
--
1.8.1.4
More information about the CRIU
mailing list