[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