Difference between revisions of "Compel"
Line 26: | Line 26: | ||
</pre> | </pre> | ||
− | + | Don't forget to put <code>compel/include/uapi/</code> directory into include paths. | |
− | |||
− | + | Then link the parasite binary. Include all the .o files needed and compel plugins <code>std</code> and <code>fds</code> by using compel linker script. | |
− | |||
− | </ | ||
− | |||
− | |||
<pre> | <pre> | ||
− | $ compel | + | $ ld foo1.o foo2.o compel/plugins/std.built-in.o compel/plugins/fds.built-ind.o -T compel/arch/$ARCH/scripts/compel-pack.lds.S -o parasite.po |
</pre> | </pre> | ||
− | The | + | The .po blob can now be loaded as parasite. |
− | |||
− | |||
== Running == | == Running == |
Revision as of 13:53, 25 November 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 parasite code always starts with a function in compel std plugin that should be linked with parasite binary (see below). From the parasite code these symbols should be available for libcompel to work
parasite_trap_cmd(int cmd, void *arg);
- This routine gets called by
compel_run_in_thread()
parasite_daemon_cmd(int cmd, void *arg);
- This routine gets called by
compel_rpc_call()
andcompel_rpc_call_sync()
parasite_cleanup(void);
- This gets called on parasite unload by
compel_cure()
Compiling and packing
Compile the source of your parasite code with compel flags:
$ gcc -c foo1.c -o foo1.o $(compel cflags)
Don't forget to put compel/include/uapi/
directory into include paths.
Then link the parasite binary. Include all the .o files needed and compel plugins std
and fds
by using compel linker script.
$ ld foo1.o foo2.o compel/plugins/std.built-in.o compel/plugins/fds.built-ind.o -T compel/arch/$ARCH/scripts/compel-pack.lds.S -o parasite.po
The .po blob can now be loaded as parasite.
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.