[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