Difference between revisions of "Compel"

From CRIU
Jump to navigation Jump to search
(reorganizing things a bit, rephrasing, English fixes)
(L3 -> L2 headers, some rephrasing)
Line 15: Line 15:
 
that should be present in your code. The <code>arg_p</code> and <code>arg_s</code> is the binary argument that will get delivered to parasite code by complel <code>_start()</code> call (see below). Sometimes this binary argument can be treated as CLI arguments argc/argv.
 
that should be present in your code. The <code>arg_p</code> and <code>arg_s</code> is the binary argument that will get delivered to parasite code by complel <code>_start()</code> call (see below). Sometimes this binary argument can be treated as CLI arguments argc/argv.
  
=== Compiling and packing ===
+
== Compiling and packing ==
  
 
Take the program and compile it with compel flags:
 
Take the program and compile it with compel flags:
Line 39: Line 39:
 
Now, the <code>foo.compel.o</code> is ready for remote execution (note that <code>foo.o</code> was not).
 
Now, the <code>foo.compel.o</code> is ready for remote execution (note that <code>foo.o</code> was not).
  
=== Execute the code ===
+
== Running ==
  
 
Using CLI, the compiled and packed parasite code can be executed like this:
 
Using CLI, the compiled and packed parasite code can be executed like this:
Line 57: Line 57:
 
These library calls require binary argument that is copied into the parasite context and is available from it via arg_p/arg_s pair. When run from CLI, the arguments are packed in the usual way (argc/argv).
 
These library calls require binary argument that is copied into the parasite context and is available from it via arg_p/arg_s pair. When run from CLI, the arguments are packed in the usual way (argc/argv).
  
=== Communicate to parasite code ===
+
== Communicating ==
  
There are several ways for doing this.
+
There are several ways to pass parameters to the parasite code.
  
 
If you run the parasite binary from CLI, the command line arguments after <code>--</code> are passed into the parasite's <code>main()</code> function.
 
If you run the parasite binary from CLI, the command line arguments after <code>--</code> are passed into the parasite's <code>main()</code> function.
Line 67: Line 67:
 
</pre>
 
</pre>
  
In <code>main()</code>, common argc and argv can be accessed using the following code:
+
In <code>main()</code>, the standard <code>argc</code> and <code>argv</code> can be obtained using the following code:
  
 
<source lang="C">
 
<source lang="C">

Revision as of 18:12, 22 September 2016

Compel is a utility to execute arbitrary code in a context of a foreign process. Compel is part of CRIU, and its sources are available from the criu-dev branch of CRIU repo, subdirectory compel.

The code to be executed is called parasite code. Once compiled with compel flags and packed, it can be executed in other task's context. Note the code is run in environment without glibc, thus it can not call the usual stdio/stdlib/etc. functions.

A set of compel plugins are provided for your convenience. Plugins get linked to the parasite binary during the pack stage.

Writing parasite code

Execution of the parasite code starts with the function

int main(void *arg_p, unsigned int arg_s);

that should be present in your code. The arg_p and arg_s is the binary argument that will get delivered to parasite code by complel _start() call (see below). Sometimes this binary argument can be treated as CLI arguments argc/argv.

Compiling and packing

Take the program and compile it with compel flags:

$ gcc -c foo1.c -o foo1.o $(compel cflags)

To combine the foo.o out of many sources, they should all be linked with compel linker flags:

$ ld foo1.o foo2.o -o foo.o $(compel ldflags)

Pack the binary. Packing would link the object file with compel plugins.

$ compel pack foo.o -o foo.compel.o [-l plugin]

The -l option specifies plugins to be added to the packed binary. The std plugin is added by default, i.e. it does not require any flags.

Now, the foo.compel.o is ready for remote execution (note that foo.o was not).

Running

Using CLI, the compiled and packed parasite code can be executed like this:

$ compel run -f foo.compel.o -p ''pid'' [args ...]

Alternatively, you can link it with the libcompel.so and use the following calls:

libcompel_exec();
libcompel_exec_start();
libcompel_exec_end();

These library calls require binary argument that is copied into the parasite context and is available from it via arg_p/arg_s pair. When run from CLI, the arguments are packed in the usual way (argc/argv).

Communicating

There are several ways to pass parameters to the parasite code.

If you run the parasite binary from CLI, the command line arguments after -- are passed into the parasite's main() function.

$ compel run -f foo.compel.o -p 123 -- arg1 arg2 arg3

In main(), the standard argc and argv can be obtained using the following code:

argc = std_argc(arg_p);
argv = std_argv(arg_p, argc);

These calls are available in argv plugin. Now, argc and argv can be handled as usual.

See also