mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +00:00
cr-service: add lazy-pages RPC feature check
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 non-zero. The RPC response is now transmitted from the forked process instead of encoding all the results into the return code. The parent RPC process now only sends an RPC message in the case of a failure. Signed-off-by: Adrian Reber <areber@redhat.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
3fdf7c02d5
commit
e82f03e1eb
@@ -852,33 +852,22 @@ static int handle_feature_check(int sk, CriuReq * msg)
|
||||
{
|
||||
CriuResp resp = CRIU_RESP__INIT;
|
||||
CriuFeatures feat = CRIU_FEATURES__INIT;
|
||||
bool success = false;
|
||||
int pid, status;
|
||||
int ret;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* From this point on the function will always
|
||||
* 'succeed'. If the requested features are supported
|
||||
* can be seen if the requested optional parameters are
|
||||
* set in the message 'criu_features'.
|
||||
*/
|
||||
success = true;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
pr_perror("Can't fork");
|
||||
@@ -886,27 +875,73 @@ static int handle_feature_check(int sk, CriuReq * msg)
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
int ret = 1;
|
||||
|
||||
setproctitle("feature-check --rpc");
|
||||
|
||||
kerndat_get_dirty_track();
|
||||
if ((msg->features->has_mem_track == 1) &&
|
||||
(msg->features->mem_track == true)) {
|
||||
|
||||
if (kdat.has_dirty_track)
|
||||
ret = 0;
|
||||
feat.mem_track = true;
|
||||
ret = kerndat_get_dirty_track();
|
||||
|
||||
if (ret)
|
||||
feat.mem_track = false;
|
||||
|
||||
if (!kdat.has_dirty_track)
|
||||
feat.mem_track = false;
|
||||
}
|
||||
|
||||
if ((msg->features->has_lazy_pages == 1) &&
|
||||
(msg->features->lazy_pages == true)) {
|
||||
ret = kerndat_uffd(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.
|
||||
*/
|
||||
if (ret)
|
||||
feat.lazy_pages = false;
|
||||
else
|
||||
feat.lazy_pages = true;
|
||||
}
|
||||
|
||||
resp.features = &feat;
|
||||
resp.type = msg->type;
|
||||
/* The feature check is working, actual results are in resp.features */
|
||||
resp.success = true;
|
||||
|
||||
/*
|
||||
* If this point is reached the information about the features
|
||||
* is transmitted from the forked CRIU process (here).
|
||||
* If an error occured earlier, the feature check response will be
|
||||
* be send from the parent process.
|
||||
*/
|
||||
ret = send_criu_msg(sk, &resp);
|
||||
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
wait(&status);
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status))
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (ret == -1)
|
||||
goto out;
|
||||
|
||||
feat.mem_track = true;
|
||||
if (WIFEXITED(status) && !WEXITSTATUS(status))
|
||||
/*
|
||||
* The child process exited was able to send the answer.
|
||||
* Nothing more to do here.
|
||||
*/
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The child process was not able to send an answer. Tell
|
||||
* the RPC client that something did not work as expected.
|
||||
*/
|
||||
out:
|
||||
resp.features = &feat;
|
||||
resp.type = msg->type;
|
||||
resp.success = success;
|
||||
resp.success = false;
|
||||
|
||||
return send_criu_msg(sk, &resp);
|
||||
}
|
||||
|
@@ -149,6 +149,7 @@ enum criu_req_type {
|
||||
*/
|
||||
message criu_features {
|
||||
optional bool mem_track = 1;
|
||||
optional bool lazy_pages = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user