[CRIU] [PATCH RESEND v3 4/4] lazy-pages: handle zombie processes
Mike Rapoport
rppt at linux.vnet.ibm.com
Fri Nov 4 08:08:04 PDT 2016
Restore of a zombie process does not call setup_uffd which causes
lazy-pages daemon to stuck forever waiting for (pid, uffd) pair to arrive.
Let's extend the protocol between restore and lazy-pages so that for zombie
process a (0, -1) pair will be sent instead of actual (uffd, pid).
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/cr-restore.c | 3 +++
criu/include/uffd.h | 1 +
criu/uffd.c | 24 ++++++++++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 3abdea8..ed1433f 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -811,6 +811,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 d8cf0d0..8adf2f0 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 a2b26d7..51b44c3 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -172,6 +172,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;
@@ -205,6 +211,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)
{
@@ -330,6 +347,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:");
@@ -865,6 +887,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;
}
--
1.9.1
More information about the CRIU
mailing list