Changes

Jump to navigation Jump to search
7,390 bytes added ,  15:57, 17 September 2016
Line 1: Line 1: −
CRIU-RPC is a remote procedure call (RPC) protocol which uses Google Protocol Buffers to encode its calls and SOCK_SEQPACKET Unix domain socket as a transport mechanism.
+
CRIU-RPC is a remote procedure call (RPC) protocol which uses Google Protocol Buffers to encode its calls. The requests are served by CRIU when either launched in so called "swrk" mode or by a service started with the <code>criu service</code> command. It uses a <code>SEQPACKET</code> Unix domain socket for transport. In case of a standalone service it listens at <code>/var/run/criu-service.socket</code> as a transport.
   −
== Preconditions ==
+
The <code>criu_req</code>/<code>criu_resp</code> are two main messages for requests/responses. They are to be used for transferring messages and needed to provide compatibility with an older versions of rpc. Field type in them ''must'' be set accordingly to type of request/response that is stored. Types of request/response are defined in <code>enum criu_req_type</code>. See the [[API compliance]] page for information what each option might mean.
Well described here: [[Self_dump]].
     −
== CRIU request ==
+
== Protocol ==
criu_req is used to wrap requests to provide compatibility with an older versions of rpc.
  −
Any request must be wrapped into criu_req to send to criu.
     −
<pre>
+
The protocol is simple: client sends a <code>criu_req</code> message to server, server responds back with <code>criu_resp</code>. In most of the cases the socket gets closed, but there are three exceptions from this rule, see below.
 +
 
 +
== Request ==
 +
 
 +
This is the header of the request. It defines the operation requested and options.
 +
 
 +
<source lang="c">
 
message criu_req {
 
message criu_req {
 
required criu_req_type type = 1;
 
required criu_req_type type = 1;
 +
optional criu_opts opts = 2;
 +
optional notify_success        = 3; /* see Notifications below */
 +
optional keep_open              = 4; /* for multi-req, below */
 +
}
 +
</source>
 +
 +
Currently, there are a few request/response types:
   −
optional criu_dump_req dump = 2;
+
<source lang="c">
 +
enum criu_req_type {
 +
EMPTY = 0;
 +
DUMP = 1; /* criu dump */
 +
RESTORE = 2; /* criu restore */
 +
CHECK = 3; /* criu check */
 +
PRE_DUMP = 4; /* criu pre-dump */
 +
PAGE_SERVER = 5; /* criu page-server */
 +
NOTIFY          = 6; /* see Notifications below */
 +
CPUINFO_DUMP = 7; /* criu cpuinfo dump */
 +
CPUINFO_CHECK = 8; /* criu cpuinfo check */
 
}
 
}
</pre>
+
</source>
   −
There is only 1 request/response type for now.
+
The following options are available:
<pre>enum criu_req_type {
+
 
EMPTY = 0;
+
<source lang="c">
DUMP = 1;
+
message criu_opts {
 +
required int32 images_dir_fd = 1;
 +
optional int32 pid = 2; /* if not set on dump, will dump requesting process */
 +
 
 +
optional bool leave_running = 3;
 +
optional bool ext_unix_sk = 4;
 +
optional bool tcp_established = 5;
 +
optional bool evasive_devices = 6;
 +
optional bool shell_job = 7;
 +
optional bool file_locks = 8;
 +
optional int32 log_level = 9 [default = 2];
 +
optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */
 +
 
 +
optional criu_page_server_info ps = 11;
 +
 
 +
optional bool notify_scripts = 12;
 +
 
 +
optional string root = 13;
 +
optional string parent_img = 14;
 +
optional bool track_mem = 15;
 +
optional bool auto_dedup = 16;
 +
 
 +
optional int32 work_dir_fd = 17;
 +
optional bool link_remap = 18;
 +
repeated criu_veth_pair veths = 19;
 +
 
 +
optional uint32 cpu_cap = 20 [default = 0xffffffff];
 +
optional bool force_irmap = 21;
 +
repeated string exec_cmd = 22;
 +
 
 +
repeated ext_mount_map ext_mnt = 23;
 +
optional bool manage_cgroups = 24;
 +
repeated cgroup_root cg_root = 25;
 +
 
 +
optional bool rst_sibling = 26; /* swrk only */
 +
}
 +
</source>
 +
 
 +
=== Comments and examples ===
 +
 
 +
* If no <code>pid</code> is set and type is <code>DUMP</code>, CRIU will dump client process by default.
 +
* All processes in the subtree starting with <code>''pid''</code> must have the same uid, as a client, or client's uid must be root (uid == 0), otherwise CRIU will return an error.
 +
* Only the <code>images_dir_fd</code> is required, all other fields are optional. Client must open directory for/with images by itself and set <code>images_dir_fd</code> to the opened <code>fd</code>. CRIU will open <code>/proc/''client_pid''/fd/''images_dir_fd''</code>.
 +
 
 +
The logic of setting request is the same as when setting options in console.
 +
 
 +
Here is an example:
 +
 
 +
# criu restore -D /path/to/imgs_dir -v4 -o restore.log
 +
 
 +
This is equal to:
 +
 
 +
<source lang="c">
 +
request.type = RESTORE;
 +
 
 +
request.opts.imgs_dir_fd = open("/path/to/imgs_dir")
 +
request.opts.log_level = 4
 +
request.opts.log_file = "restore.log"
 +
</source>
 +
 
 +
=== Sub-messages for options ===
 +
 
 +
==== Info about page-server ====
 +
 
 +
<source lang="c">
 +
message criu_page_server_info {
 +
optional string address = 1; /* bind address -- if not set 0.0.0.0 is used */
 +
optional int32 port = 2; /* bind port -- if not set on request, autobind is used and port is returned in response */
 +
optional int32 pid = 3; /* page-server pid -- returned in response */
 +
optional int32 fd = 4; /* could be used to inherit fd by page-server */
 
}
 
}
</pre>
+
</source>
=== CRIU dump request ===
+
 
criu_dump_req is used to store dump options.
+
<source lang="c">
<pre>message criu_dump_req {
+
message criu_veth_pair {
required int32 images_dir_fd = 1;
+
required string if_in = 1; /* inside veth device name */
optional int32 pid = 2;
+
required string if_out = 2; /* outside veth device name */
 +
};
 +
</source>
   −
optional bool leave_running = 3;
+
==== Info about veth mappings (<code>--ext-mount-map</code> analogue) ====
optional bool ext_unix_sk = 4;
+
<source lang="c">
optional bool tcp_established = 5;
+
message ext_mount_map {
optional bool evasive_devices = 6;
+
required string key = 1;
optional bool shell_job = 7;
+
required string val = 2;
optional bool file_locks = 8;
+
};
optional int32 log_level = 9 [default = 2];
+
</source>
}</pre>
     −
If no pid is set, CRIU will dump client process by default.
+
==== Specifying where cgroup root should be (<code>--cgroup-root</code> analogue) ====
Note: Whole tree <pid> must have the same uid, as a client, or client's uid must be == 0, otherwise CRIU won't dump nothing at all.
+
<source lang="c">
 +
message cgroup_root {
 +
optional string ctrl = 1;
 +
required string path = 2;
 +
};
 +
</source>
   −
Only images_dir_fd is required, all other fields may not be set.
+
== Response ==
Client must open directory for images by himself and set images_dir_fd to it's fd.
  −
CRIU will open /proc/<client's_pid>/fd/<images_dir_fd>, so it will work, if client is in another namespace.
     −
For other options description, please run "criu -h".
+
This message is sent after (un)successful execution of the request.
   −
== CRIU response ==
+
<source lang="c">
criu_resp is a wrapper for responses. It consists of success bool field, response type field and response, that depends on sent request type.
+
message criu_resp {
<pre>message criu_resp {
+
required criu_req_type type = 1;
required criu_req_type type = 1;
+
required bool success = 2;
required bool success = 2;
+
 
 +
optional criu_dump_resp dump = 3;
 +
optional criu_restore_resp restore = 4;
 +
optional criu_notify notify = 5;
 +
optional criu_page_server_info ps = 6;
   −
optional criu_dump_resp dump = 3;
+
        optional int32 cr_errno = 7;
 
}
 
}
</pre>
+
</source>
=== CRIU dump response ===
+
 
criu_dump_resp is used to store response from CRIU.
+
The field <code>success</code> reports result of processing request, while <code>criu_***_resp</code> store some request-specific information. The response type is set to the corresponding request type or to <code>EMPTY</code> to report a "generic" error. If <code>success == false</code>, one should check <code>cr_errno</code> field to get a more detailed error code (see [https://github.com/xemul/criu/blob/master/include/cr-errno.h#L8 include/cr-errno.h]).
<pre>
+
 
 +
==== The criu_dump_resp is used to store response from DUMP request ====
 +
 
 +
<source lang="c">
 
message criu_dump_resp {
 
message criu_dump_resp {
 
optional bool restored = 1;
 
optional bool restored = 1;
 
}
 
}
</pre>
+
</source>
 +
 
 +
This message can be sent twice — one time for the process that calls DUMP, and  another time for the same process again, in case it requested a self-dump. In the latter case the ''restored'' field would be true.
 +
 
 +
==== The response on RESTORE request ====
   −
Field "restored" is set to "true" if process was restored.
+
<source lang="c">
 +
message criu_restore_resp {
 +
required int32 pid = 1;
 +
}
 +
</source>
   −
== Server ==
+
The <code>pid</code> field is set to the PID of the newly restored process.
On a server side, CRIU creates SOCK_SEQPACKET Unix socket and listens for connections on it. After receiving criu_req, CRIU processes it, do what is requested and sends response back.
     −
To launch service server run:
+
==== Info about page server ====
   −
<pre>#criu service --address <socket_address></pre>
+
The <code>criu_page_server_info</code> from requests will be sent back on <code>PAGE_SERVER</code> request. The <code>port</code> field will contain the port to which the server is bound.
   −
If no address is set, "/tmp/criu_service.socket" is used by default.
+
=== Notifications ===
You may also like to demonize server(-d), set log level(-v<N>) or set log file(-o <logname>).
  −
For the full list of options, please run "criu -h".
     −
== Client ==
+
If the <code>opts.notify_scripts</code> in the request is set to <code>TRUE</code>, CRIU would report back resp messages with type set to <code>NOTIFY</code> and this field present. The notifications are the way [[action scripts]] work for RPC mode.
Client, in its turn, must connect to service socket, send criu_msg with request in it, and wait for a criu_resp with response.
+
 
 +
<source lang="c">
 +
message criu_notify {
 +
optional string script = 1;
 +
optional int32 pid = 2;
 +
}
 +
</source>
 +
 
 +
After handling the notification the client must response with the request again with the type set to <code>NOTIFY</code> and the <code>notify_success</code> set to the whether the notification was successful. In case of successful notification acknowledge the server doesn't close the socket and continues to work.
 +
 
 +
== Pre-dumps ==
 +
 
 +
Before issuing a <code>DUMP</code> request client may send one or more <code>PRE_DUMP</code> requests. Once the <code>PRE_DUMP</code> is sent and response is received, client may send one more <code>PRE_DUMP</code> or <code>DUMP</code> request. The server would only close the socket after the <code>DUMP</code> one.
 +
 
 +
== Multi-request mode ==
 +
 
 +
If the <code>req.keep_open</code> flag is set to true server will not close the socket after response, but will wait for more requests. This mode is supported only for the following request types:
 +
 
 +
* <code>PRE_DUMP</code> (automatically)
 +
* <code>PAGE_SERVER</code>
 +
* <code>CPUINFO_DUMP</code> and <code>CPUINFO_CHECK</code>
 +
 
 +
== Run ==
 +
 
 +
=== SWRK mode ===
 +
 
 +
This mode turns on when one <code>fork() + exec()</code> CRIU with the <code>swrk</code> action and one more argument specifying the number of descriptor with <code>SOCK_SEQPACKET</code> Unix socket. With this CRIU works as service worker task accepting standard RPC requests via the mentioned socket and using one to do action scripts notifications and result reporting.
 +
 
 +
=== Server ===
 +
 
 +
On a server side, CRIU creates <code>SOCK_SEQPACKET</code> Unix socket and listens for connections on it. After receiving <code>criu_req</code>, CRIU processes it, does what was requested and sends <code>criu_resp</code> with set request-specific <code>criu_***_resp</code> field back.
 +
If CRIU gets unknown type of request, it will return <code>criu_resp</code> with <code>type == EMPTY</code> and <code>success == false</code>.
 +
 
 +
To launch the service, run:
 +
 
 +
# criu service [options]
 +
 
 +
Options accepted by service are
 +
 
 +
; --address <path>
 +
: where to put listening socket
 +
 
 +
; --pid-file <path>
 +
: where to write pid of service process
 +
 
 +
; --daemon
 +
: tells service to daemonize
 +
 
 +
; -o <file>
 +
: says where to write logs
 +
 
 +
; -v[N]
 +
: sets the log level
 +
 
 +
==== systemd ====
 +
 
 +
If you are running systemd, you can make service start and operate automatically. First do
 +
 
 +
make install
 +
 
 +
to make files <code>criu.service</code> and <code>criu.socket</code> appear in systemd configs (<code>/lib/systemd/system/</code>).
 +
 
 +
Then run
 +
 
 +
systemctl start criu.socket
 +
 
 +
to get /var/run/criu-service.socket, and
 +
 
 +
systemctl enable criu.socket
 +
 
 +
to make <code>/var/run/criu-service.socket</code> available at boot.
 +
 
 +
=== Client ===
 +
 
 +
Client, in its turn, must connect to service socket, send <code>criu_req</code> with request in it, and wait for a <code>criu_resp</code> with response.
 
You can find examples of client programs in C and Python in test/rpc/.
 
You can find examples of client programs in C and Python in test/rpc/.
 +
 +
With RPC facilities one can perform a [[self dump]].
 +
 +
There's a [[C API|library]] that implements simple wrappers on top of RPC.
 +
 +
== See also ==
 +
* [[CLI]]
 +
* [[C API]]
 +
 +
[[Category: API]]

Navigation menu