[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