[CRIU] [rfc 3/3] inet: Introduce external inet sockets plugin call

Cyrill Gorcunov gorcunov at openvz.org
Fri Mar 7 06:43:47 PST 2014


Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 protobuf/sk-inet.proto |  6 +++++
 sk-inet.c              | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/protobuf/sk-inet.proto b/protobuf/sk-inet.proto
index dd7064bb3acb..f7dcf45a49c5 100644
--- a/protobuf/sk-inet.proto
+++ b/protobuf/sk-inet.proto
@@ -27,4 +27,10 @@ message inet_sk_entry {
 	required fown_entry		fown		= 13;
 	required sk_opts_entry		opts		= 14;
 	optional bool			v6only		= 15;
+
+	/*
+	 * The inet socket is treated as external one and
+	 * plugin should dump/restore it.
+	 */
+	optional bool			external	= 16;
 }
diff --git a/sk-inet.c b/sk-inet.c
index 02c653ff31e6..cddc6ecea562 100644
--- a/sk-inet.c
+++ b/sk-inet.c
@@ -20,6 +20,7 @@
 #include "util.h"
 #include "sockets.h"
 #include "sk-inet.h"
+#include "plugin.h"
 
 #define PB_ALEN_INET	1
 #define PB_ALEN_INET6	4
@@ -223,6 +224,64 @@ err:
 	return NULL;
 }
 
+static int dump_one_inet_fd_ext(int lfd, u32 id, const struct fd_parms *p, int family, int proto)
+{
+	InetSkEntry ie = INET_SK_ENTRY__INIT;
+	int type;
+	int ret;
+
+	ret = do_dump_opt(lfd, SOL_SOCKET, SO_TYPE, &type, sizeof(type));
+	if (ret)
+		return -1;
+
+	ret = cr_plugin_dump_inet_sk(lfd, id, family, type, proto);
+	if (ret == -ENOTSUP) {
+		return 0;
+	} else if (ret < 0) {
+		pr_err("Plugin returned %d for inet socket %x fd %d\n", ret, id, p->fd);
+		return -1;
+	}
+
+	ie.id		= id;
+	ie.family	= family;
+	ie.type		= type;
+	ie.proto	= proto;
+	ie.fown		= (FownEntry *)&p->fown;
+	ie.has_external	= true;
+	ie.external	= true;
+
+	pr_debug("Dump inet socket %x fd %d by plugin\n", id, p->fd);
+	return pb_write_one(fdset_fd(glob_fdset, CR_FD_INETSK), &ie, PB_INET_SK) == 0 ? 1 : -1;
+}
+
+static int open_inet_sk_ext(struct inet_sk_info *ii, InetSkEntry *ie, int *sk)
+{
+	int ret;
+
+	if (!ie->has_external || !ie->external)
+		return 0;
+
+	ret = cr_plugin_restore_inet_sk(ie->id, ie->family, ie->type, ie->proto);
+	if (ret == -ENOTSUP) {
+		return 0;
+	} else if (ret < 0) {
+		pr_err("Plugin returned %d for inet socket %x\n", ret, ie->id);
+		return -1;
+	}
+
+	*sk = ret;
+	pr_debug("Restore inet socket %x by plugin\n", ie->id);
+
+	futex_dec(&ii->port->users);
+
+	if (restore_fown(*sk, ie->fown)) {
+		close(*sk);
+		return -1;
+	}
+
+	return 0;
+}
+
 static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int family)
 {
 	struct inet_sk_desc *sk;
@@ -235,6 +294,12 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
 	if (ret)
 		goto err;
 
+	ret = dump_one_inet_fd_ext(lfd, id, p, family, proto);
+	if (ret > 0)
+		return 0;
+	else if (ret < 0)
+		goto err;
+
 	sk = (struct inet_sk_desc *)lookup_socket(p->stat.st_ino, family, proto);
 	if (IS_ERR(sk))
 		goto err;
@@ -471,13 +536,18 @@ static int open_inet_sk(struct file_desc *d)
 {
 	struct inet_sk_info *ii;
 	InetSkEntry *ie;
-	int sk, yes = 1;
+	int sk = -1, yes = 1;
 
 	ii = container_of(d, struct inet_sk_info, d);
 	ie = ii->ie;
 
 	show_one_inet_img("Restore", ie);
 
+	if (open_inet_sk_ext(ii, ie, &sk))
+		return -1;
+	else
+		return sk;
+
 	if (ie->family != AF_INET && ie->family != AF_INET6) {
 		pr_err("Unsupported socket family: %d\n", ie->family);
 		return -1;
-- 
1.8.3.1



More information about the CRIU mailing list