[CRIU] [PATCH 1/5] check: check whether NETLINK_REPAIR is supported or not

Andrey Vagin avagin at openvz.org
Mon Jun 13 16:35:31 PDT 2016


From: Andrew Vagin <avagin at virtuozzo.com>

The repair mode is required to restore data in a receive queue.
sendmsg() queues a message into a receive queue, if a socket
in the repair mode.

Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 criu/cr-check.c        | 15 +++++++++++++++
 criu/include/kerndat.h |  3 +++
 criu/kerndat.c         | 29 +++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/criu/cr-check.c b/criu/cr-check.c
index ca506a1..03f9d4a 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -917,6 +917,19 @@ static int check_cgroupns(void)
 	return 0;
 }
 
+static int check_nl_repair(void)
+{
+	if (kerndat_nl_repair() < 0)
+		return -1;
+
+	if (!kdat.has_nl_repair) {
+		pr_warn("NETLINK_REPAIR isn't supported.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 static int (*chk_feature)(void);
 
 /*
@@ -1021,6 +1034,7 @@ int cr_check(void)
 	 */
 	if (opts.check_experimental_features) {
 		ret |= check_autofs();
+		ret |= check_nl_repair();
 	}
 
 	print_on_level(DEFAULT_LOGLEVEL, "%s\n", ret ? CHECK_MAYBE : CHECK_GOOD);
@@ -1093,6 +1107,7 @@ static struct feature_list feature_list[] = {
 	{ "loginuid", check_loginuid },
 	{ "cgroupns", check_cgroupns },
 	{ "autofs", check_autofs },
+	{ "nl_repair", check_nl_repair },
 	{ NULL, NULL },
 };
 
diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index 15f8622..9effd02 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -30,6 +30,7 @@ struct kerndat_s {
 	bool has_dirty_track;
 	bool has_memfd;
 	bool has_fdinfo_lock;
+	bool has_nl_repair;
 	unsigned long task_size;
 	bool ipv6;
 	bool has_loginuid;
@@ -54,4 +55,6 @@ enum {
  */
 extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
 
+extern int kerndat_nl_repair();
+
 #endif /* __CR_KERNDAT_H__ */
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 8127b6e..b3e59b9 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -7,6 +7,8 @@
 #include <sys/mman.h>
 #include <errno.h>
 #include <sys/syscall.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
 
 #include "log.h"
 #include "bug.h"
@@ -22,6 +24,7 @@
 #include "proc_parse.h"
 #include "config.h"
 #include "syscall-codes.h"
+#include "sockets.h"
 
 struct kerndat_s kdat = {
 };
@@ -446,6 +449,30 @@ int kerndat_loginuid(bool only_dump)
 	return 0;
 }
 
+int kerndat_nl_repair()
+{
+	int sk, val;
+
+	sk = socket(AF_NETLINK, SOCK_DGRAM, 0);
+	if (sk < 0) {
+		pr_perror("Unable to create a netlink socket");
+		return -1;
+	}
+
+	if (setsockopt(sk, SOL_NETLINK, NETLINK_REPAIR, &val, sizeof(val))) {
+		if (errno != ENOPROTOOPT) {
+			pr_perror("Unable to set NETLINK_REPAIR");
+			close(sk);
+			return -1;
+		}
+		kdat.has_nl_repair = false;
+	} else
+		kdat.has_nl_repair = true;
+	close(sk);
+
+	return 0;
+}
+
 int kerndat_init(void)
 {
 	int ret;
@@ -467,6 +494,8 @@ int kerndat_init(void)
 		ret = get_ipv6();
 	if (!ret)
 		ret = kerndat_loginuid(true);
+	if (!ret)
+		ret = kerndat_nl_repair();
 
 	kerndat_lsm();
 
-- 
2.7.4



More information about the CRIU mailing list