diff --git a/criu/crtools.c b/criu/crtools.c index 8e3784aa4..06471f179 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -738,7 +738,7 @@ int main(int argc, char *argv[], char *envp[]) } if (!strcmp(argv[optind], "lazy-pages")) - return cr_lazy_pages() != 0; + return cr_lazy_pages(opts.daemon_mode) != 0; if (!strcmp(argv[optind], "check")) return cr_check() != 0; diff --git a/criu/include/crtools.h b/criu/include/crtools.h index 15d6d732f..a78a577cd 100644 --- a/criu/include/crtools.h +++ b/criu/include/crtools.h @@ -25,7 +25,7 @@ extern int cr_restore_tasks(void); extern int convert_to_elf(char *elf_path, int fd_core); extern int cr_check(void); extern int cr_dedup(void); -extern int cr_lazy_pages(void); +extern int cr_lazy_pages(bool daemon); extern int check_add_feature(char *arg); extern void pr_check_features(const char *offset, const char *sep, int width); diff --git a/criu/uffd.c b/criu/uffd.c index 2b3098b16..bd68a9202 100644 --- a/criu/uffd.c +++ b/criu/uffd.c @@ -15,12 +15,13 @@ #include #include #include +#include #include "linux/userfaultfd.h" #include "int.h" #include "page.h" -#include "log.h" +#include "criu-log.h" #include "criu-plugin.h" #include "pagemap.h" #include "files-reg.h" @@ -776,12 +777,9 @@ static int epoll_add_lpi(int epollfd, struct lazy_pages_info *lpi) return 0; } -static int prepare_uffds(int epollfd) +static int prepare_lazy_socket(void) { - int i; int listen; - int client; - socklen_t len; struct sockaddr_un saddr; if (prepare_sock_addr(&saddr)) @@ -793,6 +791,16 @@ static int prepare_uffds(int epollfd) return -1; } + return listen; +} + +static int prepare_uffds(int listen, int epollfd) +{ + int i; + int client; + socklen_t len; + struct sockaddr_un saddr; + /* accept new client request */ len = sizeof(struct sockaddr_un); if ((client = accept(listen, (struct sockaddr *) &saddr, &len)) < 0) { @@ -822,10 +830,11 @@ close_uffd: return -1; } -int cr_lazy_pages() +int cr_lazy_pages(bool daemon) { struct epoll_event *events; int epollfd; + int lazy_sk; int ret; if (check_for_uffd()) @@ -834,11 +843,38 @@ int cr_lazy_pages() if (lazy_pages_prepare_pstree()) return -1; + lazy_sk = prepare_lazy_socket(); + if (lazy_sk < 0) + return -1; + + if (daemon) { + ret = cr_daemon(1, 0, &lazy_sk, -1); + if (ret == -1) { + pr_err("Can't run in the background\n"); + return -1; + } + if (ret > 0) { /* parent task, daemon started */ + if (opts.pidfile) { + if (write_pidfile(ret) == -1) { + pr_perror("Can't write pidfile"); + kill(ret, SIGKILL); + waitpid(ret, NULL, 0); + return -1; + } + } + + return 0; + } + } + + if (close_status_fd()) + return -1; + epollfd = prepare_epoll(task_entries->nr_tasks, &events); if (epollfd < 0) return -1; - if (prepare_uffds(epollfd)) + if (prepare_uffds(lazy_sk, epollfd)) return -1; if (connect_to_page_server()) diff --git a/test/zdtm.py b/test/zdtm.py index 835b7809d..43b306a6f 100755 --- a/test/zdtm.py +++ b/test/zdtm.py @@ -962,11 +962,9 @@ class criu: r_opts.append('--external') r_opts.append('mnt[zdtm]:%s' % criu_dir) - lazy_pages_p = None if self.__lazy_pages: - lazy_pages_p = self.__criu_act("lazy-pages", opts = [], nowait = True) + self.__criu_act("lazy-pages", opts = ["--daemon", "--pidfile", "lp.pid"]) r_opts += ["--lazy-pages"] - time.sleep(1) # FIXME wait user fault fd socket if self.__leave_stopped: r_opts += ['--leave-stopped'] @@ -989,8 +987,8 @@ class criu: pstree_check_stopped(self.__test.getpid()) pstree_signal(self.__test.getpid(), signal.SIGCONT) - if lazy_pages_p and lazy_pages_p.wait(): - raise test_fail_exc("CRIU lazy-pages") + if self.__lazy_pages: + wait_pid_die(int(rpidfile(self.__ddir() + "/lp.pid")), "lazy pages daemon") @staticmethod def check(feature):