[CRIU] [PATCH v2] Introduce feature check via RPC

Adrian Reber adrian at lisas.de
Mon Oct 5 07:27:48 PDT 2015


From: Adrian Reber <areber at redhat.com>

There are still systems which do not support dirty memory tracking.
This offers an interface to query the dirty memory tracking availability
via the new feature check RPC.

This is in preparation of a p.haul change which will use this RPC
interface to automatically detect if pre-dumps should be executed
or not.

This change introduces an additional field in the criu_request and
criu_response message (feat_check and feat_res) which has a bit
set to 1 for a feature to check (criu_req.feat_check) and if the
feature is supported it will be still set to 1 in the response
(criu_resp.feat_res).

Right now only the check for the memory tracking feature is supported:
CRIU_FEATURES__MEM_TRACK

v2: Instead of checking for memory tracking only provide a generic
    interface to check for arbitrary features.

Signed-off-by: Adrian Reber <areber at redhat.com>
---
 cr-service.c       | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 protobuf/rpc.proto | 17 ++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/cr-service.c b/cr-service.c
index 938ea9e..6cd2215 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -32,6 +32,7 @@
 #include "security.h"
 #include "sockets.h"
 #include "irmap.h"
+#include "kerndat.h"
 
 #include "setproctitle.h"
 
@@ -723,10 +724,85 @@ static int chk_keepopen_req(CriuReq *msg)
 	else if (msg->type == CRIU_REQ_TYPE__CPUINFO_DUMP ||
 		 msg->type == CRIU_REQ_TYPE__CPUINFO_CHECK)
 		return 0;
+	else if (msg->type == CRIU_REQ_TYPE__FEATURE_CHECK)
+		return 0;
 
 	return -1;
 }
 
+/*
+ * Generic function to handle CRIU_REQ_TYPE__FEATURE_CHECK.
+ *
+ * The function will have resp.sucess = true for most cases
+ * and the actual result will be in resp.feat_res.
+ *
+ * For each feature which has been requested in msg->feat_chk
+ * the corresponding bit will be enabled in resp.feat_res.
+ */
+static int handle_feature_check(int sk, CriuReq * msg)
+{
+	CriuResp resp = CRIU_RESP__INIT;
+	bool success = false;
+	int pid, status;
+
+	/* enable setting of an optional message */
+	resp.has_feat_res = 1;
+
+	/*
+	 * 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 (!test_bit(CRIU_FEATURES__MEM_TRACK,
+		     (unsigned long *) &msg->feat_chk)) {
+		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 bits of the features are turned
+	 * on in resp.feat_res.
+	 */
+	success = true;
+
+	pid = fork();
+	if (pid < 0) {
+		pr_perror("Can't fork");
+		goto out;
+	}
+
+	if (pid == 0) {
+		int ret = 1;
+
+		if (setup_opts_from_req(sk, msg->opts))
+			goto cout;
+
+		setproctitle("feature-check --rpc -D %s", images_dir);
+
+		kerndat_get_dirty_track();
+
+		if (kdat.has_dirty_track)
+			ret = 0;
+cout:
+		exit(ret);
+	}
+
+	wait(&status);
+	if (!WIFEXITED(status) || WEXITSTATUS(status))
+		goto out;
+
+	set_bit(CRIU_FEATURES__MEM_TRACK, (unsigned long *) &resp.feat_res);
+out:
+	resp.type = msg->type;
+	resp.success = success;
+
+	return send_criu_msg(sk, &resp);
+}
+
 static int handle_cpuinfo(int sk, CriuReq *msg)
 {
 	CriuResp resp = CRIU_RESP__INIT;
@@ -804,6 +880,9 @@ more:
 	case CRIU_REQ_TYPE__CPUINFO_CHECK:
 		ret = handle_cpuinfo(sk, msg);
 		break;
+	case CRIU_REQ_TYPE__FEATURE_CHECK:
+		ret = handle_feature_check(sk, msg);
+		break;
 
 	default:
 		send_criu_err(sk, "Invalid req");
diff --git a/protobuf/rpc.proto b/protobuf/rpc.proto
index 466780e..2e04af9 100644
--- a/protobuf/rpc.proto
+++ b/protobuf/rpc.proto
@@ -115,6 +115,16 @@ enum criu_req_type {
 
 	CPUINFO_DUMP	= 7;
 	CPUINFO_CHECK	= 8;
+
+	FEATURE_CHECK	= 9;
+}
+
+/*
+ * List of features which can queried via
+ * CRIU_REQ_TYPE__FEATURE_CHECK
+ */
+enum criu_features {
+	MEM_TRACK	= 0;
 }
 
 /*
@@ -134,6 +144,12 @@ message criu_req {
 	 * for all request types.
 	 */
 	optional bool			keep_open	= 4;
+	/*
+	 * feat_chk can be used to query which features
+	 * are supported by the installed criu/kernel
+	 * via RPC.
+	 */
+	optional int32			feat_chk	= 5;
 }
 
 /*
@@ -151,4 +167,5 @@ message criu_resp {
 	optional criu_page_server_info	ps		= 6;
 
 	optional int32			cr_errno	= 7;
+	optional int32			feat_res	= 8;
 }
-- 
1.8.3.1



More information about the CRIU mailing list