diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 176383111..10413f5a9 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -942,6 +942,9 @@ static int restore_one_zombie(CoreEntry *core) if (inherit_fd_fini() < 0) return -1; + if (lazy_pages_setup_zombie()) + return -1; + prctl(PR_SET_NAME, (long)(void *)core->tc->comm, 0, 0, 0); if (task_entries != NULL) { diff --git a/criu/include/uffd.h b/criu/include/uffd.h index d8cf0d050..8adf2f0f7 100644 --- a/criu/include/uffd.h +++ b/criu/include/uffd.h @@ -3,6 +3,7 @@ struct task_restore_args; extern int setup_uffd(int pid, struct task_restore_args *task_args); +extern int lazy_pages_setup_zombie(void); extern int prepare_lazy_pages_socket(void); #endif /* __CR_UFFD_H_ */ diff --git a/criu/uffd.c b/criu/uffd.c index a8a108146..d5e706299 100644 --- a/criu/uffd.c +++ b/criu/uffd.c @@ -169,6 +169,12 @@ static int send_uffd(int sendfd, int pid) goto out; } + /* for a zombie process pid will be -1 */ + if (pid == -1) { + ret = 0; + goto out; + } + if (send_fd(fd, NULL, 0, sendfd) < 0) { pr_perror("send_fd error:"); goto out; @@ -202,6 +208,17 @@ static int check_for_uffd() return 0; } +int lazy_pages_setup_zombie(void) +{ + if (!opts.lazy_pages) + return 0; + + if (send_uffd(0, -1)) + return -1; + + return 0; +} + /* This function is used by 'criu restore --lazy-pages' */ int setup_uffd(int pid, struct task_restore_args *task_args) { @@ -331,6 +348,11 @@ static int ud_open(int client, struct lazy_pages_info **_lpi) } pr_debug("received PID: %d\n", lpi->pid); + if (lpi->pid == -1) { + lpi_fini(lpi); + return 0; + } + lpi->uffd = recv_fd(client); if (lpi->uffd < 0) { pr_perror("recv_fd error:"); @@ -866,6 +888,8 @@ static int prepare_uffds(int epollfd) struct lazy_pages_info *lpi = NULL; if (ud_open(client, &lpi)) goto close_uffd; + if (lpi == NULL) + continue; if (epoll_add_fd(epollfd, lpi->uffd)) goto close_uffd; }