[CRIU] [PATCH] dump: pre-load kernel modules

Tycho Andersen tycho.andersen at canonical.com
Tue Oct 14 00:49:29 PDT 2014


On Tue, Oct 14, 2014 at 10:48:40AM +0400, Pavel Emelyanov wrote:
> On 10/13/2014 06:12 PM, Tycho Andersen wrote:
> > See the comment below for an explanation of what is going on. We will
> > ultimately need to handle dumping the netlink data, but I think it is good to
> > prevent injecting events into the stream during a dump. So we pre-load the
> > modules, even though it isn't very pretty.
> 
> Yeah, it looks like this is the only sane way of doing this.
> Can we, btw, have this code located in sockets.c, as it's the
> one who "knows" about the _diag subsys?

Yes, something like this?


>From 9b95b9fa7621f369b0c26bbc8ecd17240dede9de Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Mon, 13 Oct 2014 13:48:58 +0000
Subject: [PATCH] dump: pre-load kernel modules

See the comment below for an explanation of what is going on. We will
ultimately need to handle dumping the netlink data, but I think it is good to
prevent injecting events into the stream during a dump. So we pre-load the
modules, even though it isn't very pretty.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 crtools.c         |  2 ++
 include/sockets.h |  1 +
 sockets.c         | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/crtools.c b/crtools.c
index a245bbb..0ac667c 100644
--- a/crtools.c
+++ b/crtools.c
@@ -473,6 +473,8 @@ int main(int argc, char *argv[], char *envp[])
 		pr_info("Will do snapshot from %s\n", opts.img_parent);
 
 	if (!strcmp(argv[optind], "dump")) {
+		preload_socket_modules();
+
 		if (!tree_id)
 			goto opt_pid_missing;
 		return cr_dump_tasks(tree_id);
diff --git a/include/sockets.h b/include/sockets.h
index 105cb10..1acb643 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -28,6 +28,7 @@ extern int dump_socket_opts(int sk, SkOptsEntry *soe);
 extern int restore_socket_opts(int sk, SkOptsEntry *soe);
 extern void release_skopts(SkOptsEntry *);
 extern int restore_prepare_socket(int sk);
+extern void preload_socket_modules();
 
 extern bool socket_test_collect_bit(unsigned int family, unsigned int proto);
 
diff --git a/sockets.c b/sockets.c
index 0268d35..6c71503 100644
--- a/sockets.c
+++ b/sockets.c
@@ -96,6 +96,41 @@ bool socket_test_collect_bit(unsigned int family, unsigned int proto)
 	return test_bit(nr, socket_cl_bits) != 0;
 }
 
+void preload_socket_modules()
+{
+	/*
+	 * If the task to dump (e.g. an LXC container) has any netlink
+	 * KOBJECT_UEVENT socket open and the _diag modules aren't
+	 * loaded is dumped, criu will freeze the task and then the
+	 * kernel will send it messages on the socket, and then we will
+	 * fail to dump because the socket has pending data. The Real
+	 * Solution is to dump this pending data, but we just modprobe
+	 * things beforehand for now so that the first dump doesn't
+	 * fail.
+	 *
+	 * We ignore failure since these could be compiled directly
+	 * in, instead of being kernel modules.
+	 */
+	char *modules[] = {
+		"netlink_diag",
+		"af_packet_diag",
+		"udp_diag",
+		"tcp_diag",
+		"unix_diag",
+		NULL,
+	};
+	int i;
+	char *args[2] = {
+		"modprobe",
+		NULL
+	};
+
+	for (i = 0; modules[i]; i++) {
+		args[1] = modules[i];
+		cr_system(-1, -1, -1, args[0], args);
+	}
+}
+
 static int dump_bound_dev(int sk, SkOptsEntry *soe)
 {
 	int ret;
-- 
1.9.1



More information about the CRIU mailing list