]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/criu.c
2 * lxc: linux Container library
4 * Copyright © 2014-2015 Canonical Ltd.
7 * Tycho Andersen <tycho.andersen@canonical.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <linux/limits.h>
30 #include <sys/mount.h>
31 #include <sys/types.h>
37 #include "bdev/bdev.h"
48 #define CRIU_VERSION "2.0"
50 #define CRIU_GITID_VERSION "2.0"
51 #define CRIU_GITID_PATCHLEVEL 0
53 lxc_log_define(lxc_criu
, lxc
);
56 /* The type of criu invocation, one of "dump" or "restore" */
59 /* The directory to pass to criu */
62 /* The container to dump */
63 struct lxc_container
*c
;
65 /* Enable criu verbose mode? */
68 /* (pre-)dump: a directory for the previous dump's images */
71 /* dump: stop the container or not after dumping? */
73 char tty_id
[32]; /* the criu tty id for /dev/console, i.e. "tty[${rdev}:${dev}]" */
75 /* restore: the file to write the init process' pid into */
77 const char *cgroup_path
;
79 /* The path that is bind mounted from /dev/console, if any. We don't
80 * want to use `--ext-mount-map auto`'s result here because the pts
81 * device may have a different path (e.g. if the pty number is
82 * different) on the target host. NULL if lxc.console = "none".
87 static int load_tty_major_minor(char *directory
, char *output
, int len
)
93 ret
= snprintf(path
, sizeof(path
), "%s/tty.info", directory
);
94 if (ret
< 0 || ret
>= sizeof(path
)) {
95 ERROR("snprintf'd too many chacters: %d", ret
);
101 /* This means we're coming from a liblxc which didn't export
102 * the tty info. In this case they had to have lxc.console =
103 * none, so there's no problem restoring.
108 SYSERROR("couldn't open %s", path
);
112 if (!fgets(output
, len
, f
)) {
114 SYSERROR("couldn't read %s", path
);
122 static void exec_criu(struct criu_opts
*opts
)
124 char **argv
, log
[PATH_MAX
];
125 int static_args
= 24, argc
= 0, i
, ret
;
129 char buf
[4096], *pos
, tty_info
[32];
131 /* If we are currently in a cgroup /foo/bar, and the container is in a
132 * cgroup /lxc/foo, lxcfs will give us an ENOENT if some task in the
133 * container has an open fd that points to one of the cgroup files
134 * (systemd always opens its "root" cgroup). So, let's escape to the
135 * /actual/ root cgroup so that lxcfs thinks criu has enough rights to
138 if (!cgroup_escape()) {
139 ERROR("failed to escape cgroups");
143 /* The command line always looks like:
144 * criu $(action) --tcp-established --file-locks --link-remap --force-irmap \
145 * --manage-cgroups action-script foo.sh -D $(directory) \
146 * -o $(directory)/$(action).log --ext-mount-map auto
147 * --enable-external-sharing --enable-external-masters
148 * --enable-fs hugetlbfs --enable-fs tracefs --ext-mount-map console:/dev/pts/n
149 * +1 for final NULL */
151 if (strcmp(opts
->action
, "dump") == 0 || strcmp(opts
->action
, "pre-dump") == 0) {
152 /* -t pid --freeze-cgroup /lxc/ct */
155 /* --prev-images-dir <path-to-directory-A-relative-to-B> */
156 if (opts
->predump_dir
)
159 /* --leave-running (only for final dump) */
160 if (strcmp(opts
->action
, "dump") == 0 && !opts
->stop
)
163 /* --external tty[88,4] */
166 } else if (strcmp(opts
->action
, "restore") == 0) {
167 /* --root $(lxc_mount_point) --restore-detached
168 * --restore-sibling --pidfile $foo --cgroup-root $foo
169 * --lsm-profile apparmor:whatever
174 if (load_tty_major_minor(opts
->directory
, tty_info
, sizeof(tty_info
)))
177 /* --inherit-fd fd[%d]:tty[%s] */
187 ret
= snprintf(log
, PATH_MAX
, "%s/%s.log", opts
->directory
, opts
->action
);
188 if (ret
< 0 || ret
>= PATH_MAX
) {
189 ERROR("logfile name too long\n");
193 argv
= malloc(static_args
* sizeof(*argv
));
197 memset(argv
, 0, static_args
* sizeof(*argv
));
199 #define DECLARE_ARG(arg) \
202 ERROR("Got NULL argument for criu"); \
205 argv[argc++] = strdup(arg); \
210 argv
[argc
++] = on_path("criu", NULL
);
212 ERROR("Couldn't find criu binary\n");
216 DECLARE_ARG(opts
->action
);
217 DECLARE_ARG("--tcp-established");
218 DECLARE_ARG("--file-locks");
219 DECLARE_ARG("--link-remap");
220 DECLARE_ARG("--force-irmap");
221 DECLARE_ARG("--manage-cgroups");
222 DECLARE_ARG("--ext-mount-map");
224 DECLARE_ARG("--enable-external-sharing");
225 DECLARE_ARG("--enable-external-masters");
226 DECLARE_ARG("--enable-fs");
227 DECLARE_ARG("hugetlbfs");
228 DECLARE_ARG("--enable-fs");
229 DECLARE_ARG("tracefs");
231 DECLARE_ARG(opts
->directory
);
236 DECLARE_ARG("-vvvvvv");
238 if (strcmp(opts
->action
, "dump") == 0 || strcmp(opts
->action
, "pre-dump") == 0) {
239 char pid
[32], *freezer_relative
;
241 if (sprintf(pid
, "%d", opts
->c
->init_pid(opts
->c
)) < 0)
247 freezer_relative
= lxc_cmd_get_cgroup_path(opts
->c
->name
,
248 opts
->c
->config_path
,
250 if (!freezer_relative
) {
251 ERROR("failed getting freezer path");
255 ret
= snprintf(log
, sizeof(log
), "/sys/fs/cgroup/freezer/%s", freezer_relative
);
256 if (ret
< 0 || ret
>= sizeof(log
))
259 DECLARE_ARG("--freeze-cgroup");
262 if (opts
->tty_id
[0]) {
263 DECLARE_ARG("--ext-mount-map");
264 DECLARE_ARG("/dev/console:console");
266 DECLARE_ARG("--external");
267 DECLARE_ARG(opts
->tty_id
);
270 if (opts
->predump_dir
) {
271 DECLARE_ARG("--prev-images-dir");
272 DECLARE_ARG(opts
->predump_dir
);
275 /* only for final dump */
276 if (strcmp(opts
->action
, "dump") == 0 && !opts
->stop
)
277 DECLARE_ARG("--leave-running");
278 } else if (strcmp(opts
->action
, "restore") == 0) {
281 struct lxc_conf
*lxc_conf
= opts
->c
->lxc_conf
;
283 DECLARE_ARG("--root");
284 DECLARE_ARG(opts
->c
->lxc_conf
->rootfs
.mount
);
285 DECLARE_ARG("--restore-detached");
286 DECLARE_ARG("--restore-sibling");
287 DECLARE_ARG("--pidfile");
288 DECLARE_ARG(opts
->pidfile
);
289 DECLARE_ARG("--cgroup-root");
290 DECLARE_ARG(opts
->cgroup_path
);
293 if (opts
->console_fd
< 0) {
294 ERROR("lxc.console configured on source host but not target");
298 ret
= snprintf(buf
, sizeof(buf
), "fd[%d]:%s", opts
->console_fd
, tty_info
);
299 if (ret
< 0 || ret
>= sizeof(buf
))
302 DECLARE_ARG("--inherit-fd");
305 if (opts
->console_name
) {
306 if (snprintf(buf
, sizeof(buf
), "console:%s", opts
->console_name
) < 0) {
307 SYSERROR("sprintf'd too many bytes");
309 DECLARE_ARG("--ext-mount-map");
313 if (lxc_conf
->lsm_aa_profile
|| lxc_conf
->lsm_se_context
) {
315 if (lxc_conf
->lsm_aa_profile
)
316 ret
= snprintf(buf
, sizeof(buf
), "apparmor:%s", lxc_conf
->lsm_aa_profile
);
318 ret
= snprintf(buf
, sizeof(buf
), "selinux:%s", lxc_conf
->lsm_se_context
);
320 if (ret
< 0 || ret
>= sizeof(buf
))
323 DECLARE_ARG("--lsm-profile");
327 additional
= lxc_list_len(&opts
->c
->lxc_conf
->network
) * 2;
329 m
= realloc(argv
, (argc
+ additional
+ 1) * sizeof(*argv
));
334 lxc_list_for_each(it
, &opts
->c
->lxc_conf
->network
) {
335 char eth
[128], *veth
;
336 struct lxc_netdev
*n
= it
->elem
;
338 if (n
->type
!= LXC_NET_VETH
)
342 if (strlen(n
->name
) >= sizeof(eth
))
344 strncpy(eth
, n
->name
, sizeof(eth
));
346 sprintf(eth
, "eth%d", netnr
);
348 veth
= n
->priv
.veth_attr
.pair
;
351 ret
= snprintf(buf
, sizeof(buf
), "%s=%s@%s", eth
, veth
, n
->link
);
353 ret
= snprintf(buf
, sizeof(buf
), "%s=%s", eth
, veth
);
354 if (ret
< 0 || ret
>= sizeof(buf
))
357 DECLARE_ARG("--veth-pair");
367 for (i
= 0; argv
[i
]; i
++) {
368 pos
= strncat(buf
, argv
[i
], buf
+ sizeof(buf
) - pos
);
369 pos
= strncat(buf
, " ", buf
+ sizeof(buf
) - pos
);
372 INFO("execing: %s", buf
);
375 execv(argv
[0], argv
);
377 for (i
= 0; argv
[i
]; i
++)
383 * Check to see if the criu version is recent enough for all the features we
384 * use. This version allows either CRIU_VERSION or (CRIU_GITID_VERSION and
385 * CRIU_GITID_PATCHLEVEL) to work, enabling users building from git to c/r
386 * things potentially before a version is released with a particular feature.
388 * The intent is that when criu development slows down, we can drop this, but
389 * for now we shouldn't attempt to c/r with versions that we know won't work.
391 static bool criu_version_ok()
396 if (pipe(pipes
) < 0) {
397 SYSERROR("pipe() failed");
403 SYSERROR("fork() failed");
408 char *args
[] = { "criu", "--version", NULL
};
412 close(STDERR_FILENO
);
413 if (dup2(pipes
[1], STDOUT_FILENO
) < 0)
416 path
= on_path("criu", NULL
);
428 if (wait_for_pid(pid
) < 0) {
430 SYSERROR("execing criu failed, is it installed?");
434 f
= fdopen(pipes
[0], "r");
440 if (fscanf(f
, "Version: %1023[^\n]s", version
) != 1)
443 if (fgetc(f
) != '\n')
446 if (strcmp(version
, CRIU_VERSION
) >= 0)
449 if (fscanf(f
, "GitID: v%1023[^-]s", version
) != 1)
455 if (fscanf(f
, "%d", &patch
) != 1)
458 if (strcmp(version
, CRIU_GITID_VERSION
) < 0)
461 if (patch
< CRIU_GITID_PATCHLEVEL
)
470 ERROR("must have criu " CRIU_VERSION
" or greater to checkpoint/restore\n");
475 /* Check and make sure the container has a configuration that we know CRIU can
477 static bool criu_ok(struct lxc_container
*c
)
481 if (!criu_version_ok())
485 ERROR("Must be root to checkpoint\n");
489 /* We only know how to restore containers with veth networks. */
490 lxc_list_for_each(it
, &c
->lxc_conf
->network
) {
491 struct lxc_netdev
*n
= it
->elem
;
498 ERROR("Found network that is not VETH or NONE\n");
506 static bool restore_net_info(struct lxc_container
*c
)
509 bool has_error
= true;
511 if (container_mem_lock(c
))
514 lxc_list_for_each(it
, &c
->lxc_conf
->network
) {
515 struct lxc_netdev
*netdev
= it
->elem
;
516 char template[IFNAMSIZ
];
518 if (netdev
->type
!= LXC_NET_VETH
)
521 snprintf(template, sizeof(template), "vethXXXXXX");
523 if (!netdev
->priv
.veth_attr
.pair
)
524 netdev
->priv
.veth_attr
.pair
= lxc_mkifname(template);
526 if (!netdev
->priv
.veth_attr
.pair
)
533 container_mem_unlock(c
);
537 // do_restore never returns, the calling process is used as the
538 // monitor process. do_restore calls exit() if it fails.
539 void do_restore(struct lxc_container
*c
, int status_pipe
, char *directory
, bool verbose
)
542 char pidfile
[L_tmpnam
];
543 struct lxc_handler
*handler
;
544 int status
, pipes
[2] = {-1, -1};
546 if (!tmpnam(pidfile
))
549 handler
= lxc_init(c
->name
, c
->lxc_conf
, c
->config_path
);
553 if (!cgroup_init(handler
)) {
554 ERROR("failed initing cgroups");
555 goto out_fini_handler
;
558 if (!cgroup_create(handler
)) {
559 ERROR("failed creating groups");
560 goto out_fini_handler
;
563 if (!restore_net_info(c
)) {
564 ERROR("failed restoring network info");
565 goto out_fini_handler
;
568 resolve_clone_flags(handler
);
570 if (pipe(pipes
) < 0) {
571 SYSERROR("pipe() failed");
572 goto out_fini_handler
;
577 goto out_fini_handler
;
581 struct lxc_rootfs
*rootfs
;
589 if (dup2(pipes
[1], STDERR_FILENO
) < 0) {
590 SYSERROR("dup2 failed");
591 goto out_fini_handler
;
594 if (dup2(pipes
[1], STDOUT_FILENO
) < 0) {
595 SYSERROR("dup2 failed");
596 goto out_fini_handler
;
599 if (unshare(CLONE_NEWNS
))
600 goto out_fini_handler
;
602 /* CRIU needs the lxc root bind mounted so that it is the root of some
604 rootfs
= &c
->lxc_conf
->rootfs
;
606 if (rootfs_is_blockdev(c
->lxc_conf
)) {
607 if (do_rootfs_setup(c
->lxc_conf
, c
->name
, c
->config_path
) < 0)
608 goto out_fini_handler
;
610 if (mkdir(rootfs
->mount
, 0755) < 0 && errno
!= EEXIST
)
611 goto out_fini_handler
;
613 if (mount(NULL
, "/", NULL
, MS_SLAVE
| MS_REC
, NULL
) < 0) {
614 SYSERROR("remount / to private failed");
615 goto out_fini_handler
;
618 if (mount(rootfs
->path
, rootfs
->mount
, NULL
, MS_BIND
, NULL
) < 0) {
619 rmdir(rootfs
->mount
);
620 goto out_fini_handler
;
624 os
.action
= "restore";
625 os
.directory
= directory
;
627 os
.pidfile
= pidfile
;
628 os
.verbose
= verbose
;
629 os
.cgroup_path
= cgroup_canonical_path(handler
);
630 os
.console_fd
= c
->lxc_conf
->console
.slave
;
632 if (os
.console_fd
>= 0) {
633 /* Twiddle the FD_CLOEXEC bit. We want to pass this FD to criu
634 * via --inherit-fd, so we don't want it to close.
636 flags
= fcntl(os
.console_fd
, F_GETFD
);
638 SYSERROR("F_GETFD failed: %d", os
.console_fd
);
639 goto out_fini_handler
;
642 flags
&= ~FD_CLOEXEC
;
644 if (fcntl(os
.console_fd
, F_SETFD
, flags
) < 0) {
645 SYSERROR("F_SETFD failed");
646 goto out_fini_handler
;
649 os
.console_name
= c
->lxc_conf
->console
.name
;
651 /* exec_criu() returning is an error */
653 umount(rootfs
->mount
);
654 rmdir(rootfs
->mount
);
655 goto out_fini_handler
;
663 pid_t w
= waitpid(pid
, &status
, 0);
666 goto out_fini_handler
;
669 ret
= write(status_pipe
, &status
, sizeof(status
));
673 if (sizeof(status
) != ret
) {
674 SYSERROR("failed to write all of status");
675 goto out_fini_handler
;
678 if (WIFEXITED(status
)) {
679 if (WEXITSTATUS(status
)) {
683 n
= read(pipes
[0], buf
, sizeof(buf
));
685 SYSERROR("failed reading from criu stderr");
686 goto out_fini_handler
;
691 ERROR("criu process exited %d, output:\n%s\n", WEXITSTATUS(status
), buf
);
692 goto out_fini_handler
;
695 FILE *f
= fopen(pidfile
, "r");
697 SYSERROR("couldn't read restore's init pidfile %s\n", pidfile
);
698 goto out_fini_handler
;
701 ret
= fscanf(f
, "%d", (int*) &handler
->pid
);
703 if (unlink(pidfile
) < 0 && errno
!= ENOENT
)
704 SYSERROR("unlinking pidfile failed");
707 ERROR("reading restore pid failed");
708 goto out_fini_handler
;
711 if (lxc_set_state(c
->name
, handler
, RUNNING
)) {
712 ERROR("error setting running state after restore");
713 goto out_fini_handler
;
717 ERROR("CRIU was killed with signal %d\n", WTERMSIG(status
));
718 goto out_fini_handler
;
724 * See comment in lxcapi_start; we don't care if these
725 * fail because it's just a beauty thing. We just
726 * assign the return here to silence potential.
728 ret
= snprintf(title
, sizeof(title
), "[lxc monitor] %s %s", c
->config_path
, c
->name
);
729 ret
= setproctitle(title
);
731 ret
= lxc_poll(c
->name
, handler
);
733 lxc_abort(c
->name
, handler
);
734 lxc_fini(c
->name
, handler
);
744 lxc_fini(c
->name
, handler
);
745 if (unlink(pidfile
) < 0 && errno
!= ENOENT
)
746 SYSERROR("unlinking pidfile failed");
749 if (status_pipe
>= 0) {
751 if (write(status_pipe
, &status
, sizeof(status
)) != sizeof(status
)) {
752 SYSERROR("writing status failed");
760 static int save_tty_major_minor(char *directory
, struct lxc_container
*c
, char *tty_id
, int len
)
767 if (c
->lxc_conf
->console
.path
&& !strcmp(c
->lxc_conf
->console
.path
, "none")) {
772 ret
= snprintf(path
, sizeof(path
), "/proc/%d/root/dev/console", c
->init_pid(c
));
773 if (ret
< 0 || ret
>= sizeof(path
)) {
774 ERROR("snprintf'd too many chacters: %d", ret
);
778 ret
= stat(path
, &sb
);
780 SYSERROR("stat of %s failed", path
);
784 ret
= snprintf(path
, sizeof(path
), "%s/tty.info", directory
);
785 if (ret
< 0 || ret
>= sizeof(path
)) {
786 ERROR("snprintf'd too many characters: %d", ret
);
790 ret
= snprintf(tty_id
, len
, "tty[%llx:%llx]",
791 (long long unsigned) sb
.st_rdev
,
792 (long long unsigned) sb
.st_dev
);
793 if (ret
< 0 || ret
>= sizeof(path
)) {
794 ERROR("snprintf'd too many characters: %d", ret
);
798 f
= fopen(path
, "w");
800 SYSERROR("failed to open %s", path
);
804 ret
= fprintf(f
, "%s", tty_id
);
807 SYSERROR("failed to write to %s", path
);
811 /* do one of either predump or a regular dump */
812 static bool do_dump(struct lxc_container
*c
, char *mode
, char *directory
,
813 bool stop
, bool verbose
, char *predump_dir
)
820 if (mkdir_p(directory
, 0700) < 0)
825 SYSERROR("fork failed");
833 os
.directory
= directory
;
836 os
.verbose
= verbose
;
837 os
.predump_dir
= predump_dir
;
838 os
.console_name
= c
->lxc_conf
->console
.path
;
840 if (save_tty_major_minor(directory
, c
, os
.tty_id
, sizeof(os
.tty_id
)) < 0)
843 /* exec_criu() returning is an error */
848 pid_t w
= waitpid(pid
, &status
, 0);
854 if (WIFEXITED(status
)) {
855 if (WEXITSTATUS(status
)) {
856 ERROR("dump failed with %d\n", WEXITSTATUS(status
));
861 } else if (WIFSIGNALED(status
)) {
862 ERROR("dump signaled with %d\n", WTERMSIG(status
));
865 ERROR("unknown dump exit %d\n", status
);
871 bool pre_dump(struct lxc_container
*c
, char *directory
, bool verbose
, char *predump_dir
)
873 return do_dump(c
, "pre-dump", directory
, false, verbose
, predump_dir
);
876 bool dump(struct lxc_container
*c
, char *directory
, bool stop
, bool verbose
, char *predump_dir
)
881 ret
= snprintf(path
, sizeof(path
), "%s/inventory.img", directory
);
882 if (ret
< 0 || ret
>= sizeof(path
))
885 if (access(path
, F_OK
) == 0) {
886 ERROR("please use a fresh directory for the dump directory\n");
890 return do_dump(c
, "dump", directory
, stop
, verbose
, predump_dir
);
893 bool restore(struct lxc_container
*c
, char *directory
, bool verbose
)
903 ERROR("Must be root to restore\n");
908 ERROR("failed to create pipe");
921 // this never returns
922 do_restore(c
, pipefd
[1], directory
, verbose
);
927 nread
= read(pipefd
[0], &status
, sizeof(status
));
929 if (sizeof(status
) != nread
) {
930 ERROR("reading status from pipe failed");
934 // If the criu process was killed or exited nonzero, wait() for the
935 // handler, since the restore process died. Otherwise, we don't need to
936 // wait, since the child becomes the monitor process.
937 if (!WIFEXITED(status
) || WEXITSTATUS(status
))
942 if (wait_for_pid(pid
))
943 ERROR("restore process died");