[CRIU] [PATCH 4/5] netlink: restore data in a received queue for netlink sockets
Andrey Vagin
avagin at openvz.org
Mon Jun 13 16:35:34 PDT 2016
From: Andrew Vagin <avagin at virtuozzo.com>
Messages from a receive queue are dumped with help of SO_PEEK_OFF
and restored back with help of NETLINK_REPAIR.
Here is nothin special, we just dump data and queue them back.
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
criu/sk-netlink.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index 8268dba..59a7ecb 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -13,6 +13,7 @@
#include "netlink_diag.h"
#include "libnetlink.h"
#include "sk-queue.h"
+#include "kerndat.h"
struct netlink_sk_desc {
struct socket_desc sd;
@@ -79,15 +80,19 @@ int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
return sk_collect_one(m->ndiag_ino, PF_NETLINK, &sd->sd);
}
-static bool can_dump_netlink_sk(int lfd)
+static bool can_dump_netlink_sk(int lfd, struct netlink_sk_desc *sk)
{
int ret;
ret = fd_has_data(lfd);
- if (ret == 1)
+ if (ret < 0)
+ return false;
+ if (ret == 1 && (sk->nl_flags & NDIAG_FLAG_CB_RUNNING)) {
pr_err("The socket has data to read\n");
+ return false;
+ }
- return ret == 0;
+ return true;
}
static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
@@ -103,7 +108,7 @@ static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
ne.id = id;
ne.ino = p->stat.st_ino;
- if (!can_dump_netlink_sk(lfd))
+ if (!can_dump_netlink_sk(lfd, sk))
goto err;
if (sk) {
@@ -151,6 +156,9 @@ static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p)
if (dump_socket_opts(lfd, &skopts))
goto err;
+ if (kdat.has_nl_repair && dump_sk_queue(lfd, id, true))
+ goto err;
+
if (pb_write_one(img_from_set(glob_imgset, CR_FD_NETLINK_SK), &ne, PB_NETLINK_SK))
goto err;
@@ -169,6 +177,29 @@ struct netlink_sock_info {
struct file_desc d;
};
+static int restore_netlink_queue(int sk, int id)
+{
+ int val;
+
+ if (!kdat.has_nl_repair)
+ return 0;
+
+ val = 1;
+ if (setsockopt(sk, SOL_NETLINK, NETLINK_REPAIR, &val, sizeof(val))) {
+ pr_perror("Unable to set NETLINK_REPAIR");
+ return -1;
+ }
+
+ if (restore_sk_queue(sk, id))
+ return -1;
+
+ val = 0;
+ if (setsockopt(sk, SOL_NETLINK, NETLINK_REPAIR, &val, sizeof(val)))
+ return -1;
+
+ return 0;
+}
+
static int open_netlink_sk(struct file_desc *d)
{
struct netlink_sock_info *nsi;
@@ -220,6 +251,9 @@ static int open_netlink_sk(struct file_desc *d)
if (restore_socket_opts(sk, nse->opts))
goto err;
+ if (restore_netlink_queue(sk, nse->id))
+ goto err;
+
return sk;
err:
close(sk);
--
2.7.4
More information about the CRIU
mailing list