[CRIU] [PATCH v3 2/2] cr-service: require non-cooperative userfaultfd for lazy-pages
Mike Rapoport
rppt at linux.vnet.ibm.com
Wed Aug 16 10:32:26 MSK 2017
Without non-cooperative userfaultfd some programs may fail during lazy
restore because they perform operations that cannot be handled by the
lazy-pages daemon.
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/cr-check.c | 9 ++-------
criu/cr-service.c | 10 ++--------
criu/include/uffd.h | 1 +
criu/uffd.c | 7 +++++++
4 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/criu/cr-check.c b/criu/cr-check.c
index caf6422..3bf335b 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -50,7 +50,7 @@
#include "libnetlink.h"
#include "net.h"
#include "restorer.h"
-#include "linux/userfaultfd.h"
+#include "uffd.h"
static char *feature_name(int (*func)());
@@ -1043,15 +1043,10 @@ static int check_uffd(void)
static int check_uffd_noncoop(void)
{
- unsigned long features = UFFD_FEATURE_EVENT_FORK |
- UFFD_FEATURE_EVENT_REMAP |
- UFFD_FEATURE_EVENT_UNMAP |
- UFFD_FEATURE_EVENT_REMOVE;
-
if (check_uffd())
return -1;
- if ((kdat.uffd_features & features) != features) {
+ if (!uffd_noncooperative()) {
pr_err("Non-cooperative UFFD is not supported\n");
return -1;
}
diff --git a/criu/cr-service.c b/criu/cr-service.c
index f0bdfa8..33d4173 100644
--- a/criu/cr-service.c
+++ b/criu/cr-service.c
@@ -40,6 +40,7 @@
#include <sys/un.h>
#include <sys/socket.h>
#include "common/scm.h"
+#include "uffd.h"
#include "setproctitle.h"
@@ -888,14 +889,7 @@ static int handle_feature_check(int sk, CriuReq * msg)
if ((msg->features->has_lazy_pages == 1) &&
(msg->features->lazy_pages == true))
- /*
- * Not checking for specific UFFD features yet.
- * If no error is returned it is probably
- * enough for basic UFFD functionality. This can
- * be extended in the future for a more detailed
- * UFFD feature check.
- */
- feat.lazy_pages = kdat.has_uffd;
+ feat.lazy_pages = kdat.has_uffd && uffd_noncooperative();
resp.features = &feat;
resp.type = msg->type;
diff --git a/criu/include/uffd.h b/criu/include/uffd.h
index e2b9be6..79abc16 100644
--- a/criu/include/uffd.h
+++ b/criu/include/uffd.h
@@ -4,6 +4,7 @@
struct task_restore_args;
extern int uffd_open(int flags, unsigned long *features);
+extern bool uffd_noncooperative(void);
extern int setup_uffd(int pid, struct task_restore_args *task_args);
extern int lazy_pages_setup_zombie(int pid);
extern int prepare_lazy_pages_socket(void);
diff --git a/criu/uffd.c b/criu/uffd.c
index d3142ae..077724b 100644
--- a/criu/uffd.c
+++ b/criu/uffd.c
@@ -211,6 +211,13 @@ int lazy_pages_setup_zombie(int pid)
return 0;
}
+bool uffd_noncooperative(void)
+{
+ unsigned long features = NEED_UFFD_API_FEATURES;
+
+ return (kdat.uffd_features & features) == features;
+}
+
int uffd_open(int flags, unsigned long *features)
{
struct uffdio_api uffdio_api = { 0 };
--
2.7.4
More information about the CRIU
mailing list