From c443faca3fa8c06b94b3b67be5b6a12d71ef0b3e Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Wed, 4 May 2016 11:22:00 +0300 Subject: [PATCH] criu: uffd runtime detection Now that userfaultfd/lazy-pages support is enable all the time, this adds runtime detection of userfaultfd. On a system without the userfaultfd syscall following is printed: uffd daemon: (00.000004) Error (uffd.c:176): lazy-pages: Runtime detection of userfaultfd failed on this system. (00.000024) Error (uffd.c:177): lazy-pages: Processes cannot be lazy-restored on this system. or criu restore (00.457047) 6858: Error (uffd.c:176): lazy-pages: Runtime detection of userfaultfd failed on this system. (00.457049) 6858: Error (uffd.c:177): lazy-pages: Processes cannot be lazy-restored on this system. Signed-off-by: Adrian Reber Acked-by: Mike Rapoport Signed-off-by: Pavel Emelyanov --- criu/uffd.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/criu/uffd.c b/criu/uffd.c index 9a19a8aba..c3f62424a 100644 --- a/criu/uffd.c +++ b/criu/uffd.c @@ -160,10 +160,33 @@ out: return ret; } +/* Runtime detection if userfaultfd can be used */ + +static int check_for_uffd() +{ + int uffd; + + uffd = syscall(SYS_userfaultfd, 0); + /* + * uffd == -1 is probably enough to not use lazy-restore + * on this system. Additionally checking for ENOSYS + * makes sure it is actually not implemented. + */ + if ((uffd == -1) && (errno == ENOSYS)) { + pr_err("Runtime detection of userfaultfd failed on this system.\n"); + pr_err("Processes cannot be lazy-restored on this system.\n"); + return -1; + } + close(uffd); + return 0; +} + /* This function is used by 'criu restore --lazy-pages' */ int setup_uffd(struct task_restore_args *task_args, int pid) { struct uffdio_api uffdio_api; + if (check_for_uffd()) + return -1; /* * Open userfaulfd FD which is passed to the restorer blob and * to a second process handling the userfaultfd page faults. @@ -810,6 +833,9 @@ int cr_lazy_pages() int epollfd; int ret; + if (check_for_uffd()) + return -1; + if (!opts.addr) { pr_info("Please specify a file name for the unix domain socket\n"); pr_info("used to communicate between the lazy-pages server\n");