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

Pavel Emelyanov xemul at parallels.com
Tue Oct 14 03:21:38 PDT 2014


On 10/14/2014 11:49 AM, Tycho Andersen wrote:
> 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?

Yup :) Thanks!

> 
>>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;
> 



More information about the CRIU mailing list