lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Fri, 10 Apr 2009 06:40:19 +0400
From:	Alexey Dobriyan <adobriyan@...il.com>
To:	akpm@...ux-foundation.org, containers@...ts.linux-foundation.org
Cc:	xemul@...allels.com, serue@...ibm.com, dave@...ux.vnet.ibm.com,
	mingo@...e.hu, orenl@...columbia.edu, hch@...radead.org,
	torvalds@...ux-foundation.org, linux-kernel@...r.kernel.org
Subject: [PATCH 27/30] cr: deal with netns

netns is full of questions too.

Restore netns itself, and core.somaxconn, unix.max_dgram_qlen for start.

Signed-off-by: Alexey Dobriyan <adobriyan@...il.com>
---

 include/linux/cr.h     |   13 +++++
 kernel/cr/Kconfig      |    1 
 kernel/cr/Makefile     |    1 
 kernel/cr/cpt-sys.c    |    6 ++
 kernel/cr/cr-net.c     |  115 +++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/cr/cr-nsproxy.c |   21 ++++++++
 kernel/cr/cr.h         |   27 +++++++++++
 7 files changed, 183 insertions(+), 1 deletion(-)

--- a/include/linux/cr.h
+++ b/include/linux/cr.h
@@ -49,6 +49,7 @@ struct cr_object_header {
 #define CR_OBJ_USER_STRUCT	18
 #define CR_OBJ_USER_NS		19
 #define CR_OBJ_MNT_NS		20
+#define CR_OBJ_NET_NS		21
 	__u32	cr_type;	/* object type */
 	__u32	cr_len;		/* object length in bytes including header */
 } __packed;
@@ -179,6 +180,7 @@ struct cr_image_nsproxy {
 	cr_pos_t	cr_pos_uts_ns;
 	cr_pos_t	cr_pos_mnt_ns;
 	cr_pos_t	cr_pos_pid_ns;
+	cr_pos_t	cr_pos_net_ns;	/* CR_POS_UNDEF if CONFIG_NET=n */
 } __packed;
 
 struct cr_image_uts_ns {
@@ -360,4 +362,15 @@ struct cr_image_pid {
 	__u32		cr_level;
 	__u32		cr_nr[1];	/* cr_nr[cr_level + 1] */
 } __packed;
+
+struct cr_image_net_ns {
+	struct cr_object_header cr_hdr;
+
+	struct {
+		__u32	cr_sysctl_somaxconn;
+	} cr_core;
+	struct {
+		__u32	cr_sysctl_max_dgram_qlen;
+	} cr_unx;
+} __packed;
 #endif
--- a/kernel/cr/Kconfig
+++ b/kernel/cr/Kconfig
@@ -1,5 +1,6 @@
 config CR
 	bool "Container checkpoint/restart"
+	depends on NET_NS || (NET = n)
 	depends on PID_NS
 	depends on USER_NS
 	depends on UTS_NS
--- a/kernel/cr/Makefile
+++ b/kernel/cr/Makefile
@@ -6,6 +6,7 @@ cr-y += cr-file.o
 cr-y += cr-fs.o
 cr-y += cr-mm.o
 cr-y += cr-mnt.o
+cr-$(CONFIG_NET) += cr-net.o
 cr-y += cr-nsproxy.o
 cr-y += cr-pid.o
 cr-y += cr-signal.o
--- a/kernel/cr/cpt-sys.c
+++ b/kernel/cr/cpt-sys.c
@@ -86,6 +86,9 @@ static int cr_collect(struct cr_context *ctx)
 	rv = cr_collect_all_file(ctx);
 	if (rv < 0)
 		return rv;
+	rv = cr_collect_all_net_ns(ctx);
+	if (rv < 0)
+		return rv;
 	rv = cr_collect_all_fs_struct(ctx);
 	if (rv < 0)
 		return rv;
@@ -176,6 +179,9 @@ static int cr_dump(struct cr_context *ctx)
 	rv = cr_dump_all_uts_ns(ctx);
 	if (rv < 0)
 		return rv;
+	rv = cr_dump_all_net_ns(ctx);
+	if (rv < 0)
+		return rv;
 	rv = cr_dump_all_sighand_struct(ctx);
 	if (rv < 0)
 		return rv;
new file mode 100644
--- /dev/null
+++ b/kernel/cr/cr-net.c
@@ -0,0 +1,115 @@
+/* Copyright (C) 2000-2009 Parallels Holdings, Ltd. */
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include <linux/cr.h>
+#include "cr.h"
+
+static int cr_collect_net_ns(struct cr_context *ctx, struct net *net_ns)
+{
+	int rv;
+
+	rv = cr_collect_object(ctx, net_ns, CR_CTX_NET_NS);
+	printk("collect net_ns %p: rv %d\n", net_ns, rv);
+	return rv;
+}
+
+int cr_collect_all_net_ns(struct cr_context *ctx)
+{
+	struct cr_object *obj;
+	int rv;
+
+	for_each_cr_object(ctx, obj, CR_CTX_NSPROXY) {
+		struct nsproxy *nsproxy = obj->o_obj;
+
+		rv = cr_collect_net_ns(ctx, nsproxy->net_ns);
+		if (rv < 0)
+			return rv;
+	}
+	for_each_cr_object(ctx, obj, CR_CTX_NET_NS) {
+		struct net *net_ns = obj->o_obj;
+		unsigned int cnt = atomic_read(&net_ns->count);
+
+		if (obj->o_count != cnt) {
+			printk("%s: net_ns %p has external references %lu:%u\n", __func__, net_ns, obj->o_count, cnt);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int cr_dump_net_ns(struct cr_context *ctx, struct cr_object *obj)
+{
+	struct net *net = obj->o_obj;
+	struct cr_image_net_ns *i;
+	int rv;
+
+	printk("dump net_ns %p\n", net);
+
+	i = cr_prepare_image(CR_OBJ_NET_NS, sizeof(*i));
+	if (!i)
+		return -ENOMEM;
+
+	i->cr_core.cr_sysctl_somaxconn = net->core.sysctl_somaxconn;
+	i->cr_unx.cr_sysctl_max_dgram_qlen = net->unx.sysctl_max_dgram_qlen;
+
+	obj->o_pos = ctx->cr_dump_file->f_pos;
+	rv = cr_write(ctx, i, sizeof(*i));
+	kfree(i);
+	return rv;
+}
+
+int cr_dump_all_net_ns(struct cr_context *ctx)
+{
+	struct cr_object *obj;
+	int rv;
+
+	for_each_cr_object(ctx, obj, CR_CTX_NET_NS) {
+		rv = cr_dump_net_ns(ctx, obj);
+		if (rv < 0)
+			return rv;
+	}
+	return 0;
+}
+
+int cr_restore_net_ns(struct cr_context *ctx, loff_t pos)
+{
+	struct cr_image_net_ns *i;
+	struct net *net;
+	struct cr_object *obj;
+	int rv;
+
+	i = kzalloc(sizeof(*i), GFP_KERNEL);
+	if (!i)
+		return -ENOMEM;
+	rv = cr_pread(ctx, i, sizeof(*i), pos);
+	if (rv < 0) {
+		kfree(i);
+		return rv;
+	}
+	if (i->cr_hdr.cr_type != CR_OBJ_NET_NS) {
+		kfree(i);
+		return -EINVAL;
+	}
+
+	net = net_create();
+	if (IS_ERR(net)) {
+		kfree(i);
+		return PTR_ERR(net);
+	}
+
+	net->core.sysctl_somaxconn = i->cr_core.cr_sysctl_somaxconn;
+	net->unx.sysctl_max_dgram_qlen = i->cr_unx.cr_sysctl_max_dgram_qlen;
+	kfree(i);
+
+	obj = cr_object_create(net);
+	if (!obj) {
+		put_net(net);
+		return -ENOMEM;
+	}
+	obj->o_pos = pos;
+	list_add(&obj->o_list, &ctx->cr_obj[CR_CTX_NET_NS]);
+	printk("restore net_ns %p, pos %lld\n", net, (long long)pos);
+	return 0;
+}
--- a/kernel/cr/cr-nsproxy.c
+++ b/kernel/cr/cr-nsproxy.c
@@ -63,6 +63,12 @@ static int cr_dump_nsproxy(struct cr_context *ctx, struct cr_object *obj)
 	i->cr_pos_mnt_ns = tmp->o_pos;
 	tmp = cr_find_obj_by_ptr(ctx, nsproxy->pid_ns, CR_CTX_PID_NS);
 	i->cr_pos_pid_ns = tmp->o_pos;
+#ifdef CONFIG_NET
+	tmp = cr_find_obj_by_ptr(ctx, nsproxy->net_ns, CR_CTX_NET_NS);
+	i->cr_pos_net_ns = tmp->o_pos;
+#else
+	i->cr_pos_net_ns = CR_POS_UNDEF;
+#endif
 
 	obj->o_pos = ctx->cr_dump_file->f_pos;
 	rv = cr_write(ctx, i, sizeof(*i));
@@ -89,6 +95,9 @@ static int __cr_restore_nsproxy(struct cr_context *ctx, loff_t pos)
 	struct nsproxy *nsproxy;
 	struct uts_namespace *uts_ns;
 	struct pid_namespace *pid_ns;
+#ifdef CONFIG_NET
+	struct net *net;
+#endif
 	struct cr_object *obj, *tmp;
 	int rv;
 
@@ -145,7 +154,17 @@ static int __cr_restore_nsproxy(struct cr_context *ctx, loff_t pos)
 	nsproxy->pid_ns = get_pid_ns(pid_ns);
 
 #ifdef CONFIG_NET
-	nsproxy->net_ns = get_net(&init_net);
+	tmp = cr_find_obj_by_pos(ctx, i->cr_pos_net_ns, CR_CTX_NET_NS);
+	if (!tmp) {
+		rv = cr_restore_net_ns(ctx, i->cr_pos_net_ns);
+		if (rv < 0) {
+			kfree(i);
+			return rv;
+		}
+		tmp = cr_find_obj_by_pos(ctx, i->cr_pos_net_ns, CR_CTX_NET_NS);
+	}
+	net = tmp->o_obj;
+	nsproxy->net_ns = get_net(net);
 #endif
 	kfree(i);
 
--- a/kernel/cr/cr.h
+++ b/kernel/cr/cr.h
@@ -29,6 +29,9 @@ enum cr_context_obj_type {
 	CR_CTX_GROUP_INFO,
 	CR_CTX_MM_STRUCT,
 	CR_CTX_MNT_NS,
+#ifdef CONFIG_NET
+	CR_CTX_NET_NS,
+#endif
 	CR_CTX_NSPROXY,
 	CR_CTX_PID,
 	CR_CTX_PID_NS,
@@ -97,6 +100,14 @@ int cr_collect_all_fs_struct(struct cr_context *ctx);
 int cr_collect_all_group_info(struct cr_context *ctx);
 int cr_collect_all_mm_struct(struct cr_context *ctx);
 int cr_collect_all_mnt_ns(struct cr_context *ctx);
+#ifdef CONFIG_NET
+int cr_collect_all_net_ns(struct cr_context *ctx);
+#else
+static inline int cr_collect_all_net_ns(struct cr_context *ctx)
+{
+	return 0;
+}
+#endif
 int cr_collect_all_nsproxy(struct cr_context *ctx);
 int cr_collect_all_pid_ns(struct cr_context *ctx);
 int cr_collect_all_pid(struct cr_context *ctx);
@@ -114,6 +125,14 @@ int cr_dump_all_fs_struct(struct cr_context *ctx);
 int cr_dump_all_group_info(struct cr_context *ctx);
 int cr_dump_all_mm_struct(struct cr_context *ctx);
 int cr_dump_all_mnt_ns(struct cr_context *ctx);
+#ifdef CONFIG_NET
+int cr_dump_all_net_ns(struct cr_context *ctx);
+#else
+static inline int cr_dump_all_net_ns(struct cr_context *ctx)
+{
+	return 0;
+}
+#endif
 int cr_dump_all_nsproxy(struct cr_context *ctx);
 int cr_dump_all_pid_ns(struct cr_context *ctx);
 int cr_dump_all_pid(struct cr_context *ctx);
@@ -131,6 +150,14 @@ int cr_restore_fs_struct(struct cr_context *ctx, loff_t pos);
 int cr_restore_group_info(struct cr_context *ctx, loff_t pos);
 int cr_restore_mm_struct(struct cr_context *ctx, loff_t pos);
 int cr_restore_mnt_ns(struct cr_context *ctx, loff_t pos);
+#ifdef CONFIG_NET
+int cr_restore_net_ns(struct cr_context *ctx, loff_t pos);
+#else
+static inline int cr_restore_net_ns(struct cr_context *ctx, loff_t pos)
+{
+	return 0;
+}
+#endif
 int cr_restore_nsproxy(struct cr_context *ctx, loff_t pos);
 int cr_restore_pid_ns(struct cr_context *ctx, loff_t pos);
 int cr_restore_pid(struct cr_context *ctx, struct cr_image_task_struct *i);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists