[CRIU] [PATCH] cr-service: add lazy-pages RPC feature check
Andrei Vagin
avagin at virtuozzo.com
Thu Feb 16 17:36:05 PST 2017
On Thu, Feb 16, 2017 at 12:00:26PM +0100, Adrian Reber wrote:
> From: Adrian Reber <areber at redhat.com>
>
> Extend the RPC feature check functionality to also test for lazy-pages
> support. This does not check for certain UFFD features (yet). Right now
> it only checks if kerndat_uffd() returns a least one UFFD feature.
>
> Signed-off-by: Adrian Reber <areber at redhat.com>
> ---
> criu/cr-service.c | 39 ++++++++++++++++++++++++++-------------
> images/rpc.proto | 1 +
> 2 files changed, 27 insertions(+), 13 deletions(-)
>
> diff --git a/criu/cr-service.c b/criu/cr-service.c
> index ff5a7a8..3e15e5f 100644
> --- a/criu/cr-service.c
> +++ b/criu/cr-service.c
> @@ -829,15 +829,12 @@ static int handle_feature_check(int sk, CriuReq * msg)
> /* enable setting of an optional message */
> feat.has_mem_track = 1;
> feat.mem_track = false;
> + feat.has_lazy_pages = 1;
> + feat.lazy_pages = false;
>
> - /*
> - * Check if the requested feature check can be answered.
> - *
> - * This function is right now hard-coded to memory
> - * tracking detection and needs other/better logic to
> - * handle multiple feature checks.
> - */
> - if (msg->features->has_mem_track != 1) {
> + /* Check if the requested feature check can be answered. */
> + if ((msg->features->has_mem_track != 1) ||
> + (msg->features->has_lazy_pages != 1)) {
> pr_warn("Feature checking for unknown feature.\n");
> goto out;
> }
> @@ -850,6 +847,9 @@ static int handle_feature_check(int sk, CriuReq * msg)
> */
> success = true;
>
> +#define HAS_MEM_TRACK (1<<0)
> +#define HAS_LAZY_PAGES (1<<1)
> +
> pid = fork();
> if (pid < 0) {
> pr_perror("Can't fork");
> @@ -857,23 +857,36 @@ static int handle_feature_check(int sk, CriuReq * msg)
> }
>
> if (pid == 0) {
> - int ret = 1;
> + int rc = -1;
> + int ret = 0;
>
> setproctitle("feature-check --rpc");
>
> - kerndat_get_dirty_track();
> + if ((msg->features->has_mem_track == 1) &&
> + (msg->features->mem_track == true))
> + kerndat_get_dirty_track();
>
> if (kdat.has_dirty_track)
> - ret = 0;
> + ret |= HAS_MEM_TRACK;
> +
> + if ((msg->features->has_lazy_pages == 1) &&
> + (msg->features->lazy_pages == true))
> + rc = kerndat_uffd(true);
> +
> + if ((rc != -1) && kdat.uffd_features)
> + ret |= HAS_LAZY_PAGES;
>
> exit(ret);
> }
>
> wait(&status);
> - if (!WIFEXITED(status) || WEXITSTATUS(status))
> + if (!WIFEXITED(status))
> goto out;
>
> - feat.mem_track = true;
> + if (WEXITSTATUS(status) == (HAS_MEM_TRACK & 0xff))
> + feat.mem_track = true;
> + if (WEXITSTATUS(status) == (HAS_LAZY_PAGES & 0xff))
> + feat.lazy_pages = true;
I think something wrong here ^^^^. This code can not set feat.mem_track
and feat.lazy_pages together.
maybe you mean something like this:
status = WEXITSTATUS(status);
if (status & HAS_MEM_TRACK)
feat.mem_track = true;
if (status & HAS_LAZY_PAGES)
feat.lazy_pages = true;
I don't like a game with a process exit code. We don't check exit codes
of kerndat_uffd and kerndat_get_dirty_track, but I think we should.
Why do we need to create a new process to call these functions?
> out:
> resp.features = &feat;
> resp.type = msg->type;
> diff --git a/images/rpc.proto b/images/rpc.proto
> index f924b73..f894ae1 100644
> --- a/images/rpc.proto
> +++ b/images/rpc.proto
> @@ -148,6 +148,7 @@ enum criu_req_type {
> */
> message criu_features {
> optional bool mem_track = 1;
> + optional bool lazy_pages = 2;
> }
>
> /*
> --
> 2.9.3
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list