mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 05:48:05 +00:00
cr-service: require non-cooperative userfaultfd for lazy-pages
Without non-cooperative userfaultfd some programs may fail during lazy restore because they perform operations that cannot be handled by the lazy-pages daemon. ✓ travis-ci: success for lazy-pages: update checks for availability of userfaultfd (rev3) Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
6a17d8cf49
commit
9c56992f2b
@ -50,7 +50,7 @@
|
|||||||
#include "libnetlink.h"
|
#include "libnetlink.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "restorer.h"
|
#include "restorer.h"
|
||||||
#include "linux/userfaultfd.h"
|
#include "uffd.h"
|
||||||
|
|
||||||
static char *feature_name(int (*func)());
|
static char *feature_name(int (*func)());
|
||||||
|
|
||||||
@ -1043,15 +1043,10 @@ static int check_uffd(void)
|
|||||||
|
|
||||||
static int check_uffd_noncoop(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())
|
if (check_uffd())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((kdat.uffd_features & features) != features) {
|
if (!uffd_noncooperative()) {
|
||||||
pr_err("Non-cooperative UFFD is not supported\n");
|
pr_err("Non-cooperative UFFD is not supported\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include "common/scm.h"
|
#include "common/scm.h"
|
||||||
|
#include "uffd.h"
|
||||||
|
|
||||||
#include "setproctitle.h"
|
#include "setproctitle.h"
|
||||||
|
|
||||||
@ -891,14 +892,7 @@ static int handle_feature_check(int sk, CriuReq * msg)
|
|||||||
|
|
||||||
if ((msg->features->has_lazy_pages == 1) &&
|
if ((msg->features->has_lazy_pages == 1) &&
|
||||||
(msg->features->lazy_pages == true))
|
(msg->features->lazy_pages == true))
|
||||||
/*
|
feat.lazy_pages = kdat.has_uffd && uffd_noncooperative();
|
||||||
* 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;
|
|
||||||
|
|
||||||
resp.features = &feat;
|
resp.features = &feat;
|
||||||
resp.type = msg->type;
|
resp.type = msg->type;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
struct task_restore_args;
|
struct task_restore_args;
|
||||||
|
|
||||||
extern int uffd_open(int flags, unsigned long *features);
|
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 setup_uffd(int pid, struct task_restore_args *task_args);
|
||||||
extern int lazy_pages_setup_zombie(int pid);
|
extern int lazy_pages_setup_zombie(int pid);
|
||||||
extern int prepare_lazy_pages_socket(void);
|
extern int prepare_lazy_pages_socket(void);
|
||||||
|
@ -211,6 +211,13 @@ int lazy_pages_setup_zombie(int pid)
|
|||||||
return 0;
|
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)
|
int uffd_open(int flags, unsigned long *features)
|
||||||
{
|
{
|
||||||
struct uffdio_api uffdio_api = { 0 };
|
struct uffdio_api uffdio_api = { 0 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user