2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 05:48:05 +00:00

7582 Commits

Author SHA1 Message Date
Pavel Emelyanov
4fdc20ed40 soccr/tcp: Introduce blob with connection info and getter for it
As an API for dumping and restoring the data the structure
with __u32-s is used. Getting one (and restoring) also involve
the size of the structure so that both -- caller and library --
can know which "version" of it the other one is using.

As a starting point all the fields that tcp_entry carries are
used.

Also note, that only tcp connection info is handled by the
library. Stuff like addresses and ports, socket options and
other are left for the caller to care for.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-16 11:03:41 +03:00
Pavel Emelyanov
b8b113bf56 soccr/tcp: Add _pause and _resume to library and use it
The calls put socket into a mode where it can be saved or
restored. Add take one out of this mode.

TODO: In criu we turn repair off (resume the socket) from
restorer blob that cannot use the library. Need to somehow
fix it.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-16 11:03:41 +03:00
Pavel Emelyanov
e3f270ac05 soccr: Add logging
In order to get messages from libsoccr I propose to
introduce a printing callback that can be set by library
user and that will be called by libsoccr.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-16 11:03:41 +03:00
Pavel Emelyanov
6d9e6d15bf soccr: Wire into builder
For now build the .a library not to produce criu wrappers.
Next version should include the .so library as well.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-16 11:03:41 +03:00
Kirill Tkhai
741719e8d3 ns: Fix error return value in __get_ns_id()
Function has unsigned int return value, and error is coded by 0, not -1.

travis-ci: success for ns: Fix error return value in __get_ns_id()
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:07 +03:00
Dmitry Safonov
8cae4bdcfa zdtm/test: add infop to waitid()
The man page says, it's not optional argument:
  The application shall ensure that the infop argument
  points to a siginfo_t structure.

Fixes:
Test output: ================================
17:40:26.128:     5: FAIL: helper_zombie_child.c:33: waitid (errno = 14 (Bad address))
17:40:26.128:     4: FAIL: helper_zombie_child.c:78: read (errno = 2 (No such file or directory))
17:40:26.129:     3: ERR: test.c:229: Test exited unexpectedly with code 1

Test output: ================================
15:30:49.021:    30: ERR: sigpending.c:213: waitid (errno = 14 (Bad address))
15:30:49.021:    29: ERR: test.c:229: Test exited unexpectedly with code 1

and etc.

travis-ci: success for 32-bit tests fixes
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Acked-by: Tycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:06 +03:00
Vitaly Ostrosablin
ae48b5d676 test: add variable delta for poll.c test
For ZDTM purposes, poll.c uses delta of 5 seconds, which is fine, since
tests don't take a very long time to pass. However, in vzt-cpt, we start
a batch with multitude of tests and starting them all could take over an
hour. Hence, the test is bound to fail. An easy solution would be to
introduce an environment variable, which would allow to specify the
delta - ZDTM_DELTA. If it's unset (which is default behaviour in ZDTM) -
it would default to 5 seconds. However, if it's set (what we can do from
vzt-cpt) - then it will use delta which is set by our test.

travis-ci: success for test: add variable delta for poll.c test (rev2)
Signed-off-by: Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:06 +03:00
Andrei Vagin
1418492fd2 files: don't leak a file descriptor
CID 173737 (#1 of 2): Resource leak (RESOURCE_LEAK)
9. leaked_handle: Handle variable rmntns_root going out of scope leaks the handle.

travis-ci: success for files: don't leak a file descriptor
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:06 +03:00
Pavel Emelyanov
a99b7c1ba3 page-server: Allow blocking on socket
When splicing page server data from UNIX socket we may get
error (EAGAIN) from splice if no data is available on the
socket yet. This is because the SPLICE_F_NONBLOCK flag is
checked by af_unix.c in the kernel to decide whether or
not to do blocking read.

This is not symmetrical with TCP sockets, which only check
for the socket's O_NONBLOCK flag for the same decicion.

Dropping the SPLICE_F_NONBLOCK flag is not possible too, as
otherwise we'll block on the pipe when trying to put data
into it. Even if part of the data fits into it kernel would
block anyway untill full buffer is in. And there will be
no read() from the pipe, as it should happen one step later
in the same task.

So to untie this, we need to wait for the data explicitly
with poll().

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:06 +03:00
Andrei Vagin
aabeb8e46d zdtm: use a unix socket instead of a pipe to synchronizer processes
A unix socket can be bound to itself, so we need only one socket
instead of a pair of pipe.

If we use a socket, we can peek a message and if it isn't for us
we don't need to send it back.

Currently a process reads message from pipe, if it isn't for him,
it sends it back and sleeps for a random timeout. In a worst case
each waiter will read and send a message back, before the right
one will get it.

travis-ci: success for series starting with [1/3] zdtm: call test_init() before doing anything
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:06 +03:00
Andrei Vagin
f5df0adac6 travis: build tests in docker containers
travis-ci: success for series starting with [1/3] zdtm: call test_init() before doing anything
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:30:05 +03:00
Andrei Vagin
4c3068cfca zdtm: call test_init() before doing anything
test_init() has to be executed first, because it prepares a container.

travis-ci: success for series starting with [1/3] zdtm: call test_init() before doing anything
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:29:29 +03:00
Cyrill Gorcunov
02cdd46dd3 rst-malloc: Update deprecated MAP_ANON flag
travis-ci: success for Fetch mmap_minimal_address and drop MAP_ANON
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:29:29 +03:00
Cyrill Gorcunov
1296fff7db restore: Fetch mmap_minimal_address runtime
We assume that mmap_minimal_address with non-default
setting is not widespread but it's not true. Instead
lets fetch this setting runtime.

travis-ci: success for Fetch mmap_minimal_address and drop MAP_ANON
Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:29:28 +03:00
Gleb Valin
7a6b96aed7 zdtm: Add test for SOCK_PACKET sockets
This one covers the following cases:
* socket is bound to an interface
* socket isn't bound to an interface

https://github.com/xemul/criu/issues/73
travis-ci: success for series starting with [1/2] socket: Add support for SOCK_PACKET sockets
Signed-off-by: Gleb Valin <the7winds@yandex.ru>
Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Gleb Valin
6d86d8d0d1 socket: Add support for SOCK_PACKET sockets
If socket type is SOCK_PACKET it restores binding with proper address structure.

https://github.com/xemul/criu/issues/73
travis-ci: success for series starting with [1/2] socket: Add support for SOCK_PACKET sockets
Signed-off-by: Gleb Valin <the7winds@yandex.ru>
Signed-off-by: Eugene Batalov <eabatalov89@gmail.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Vitaly Ostrosablin
b82fc5e07c test: fix shell script tests (conntracks & route_rules)
Test seem to assume that zdtm lib directory is on PATH, but if it's not
- calling for parseargs.sh would fail (if cwd is static). Therefore,
this patch changes this to ../lib/parseargs.sh which should be fine both
for zdtm and vzt-cpt.

travis-ci: success for test: fix shell script tests (conntracks & route_rules)
Signed-off-by: Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Adrian Reber
9a5ff1a075 zdtm: fix '"makedev" is defined by <sys/sysmacros.h>'
Compiling zdtm on the latest Fedora rawhide gives errors like this:

ns.c: In function ‘prepare_mntns’:
ns.c:122:13: error: In the GNU C Library, "makedev" is defined
 by <sys/sysmacros.h>. For historical compatibility, it is
 currently defined by <sys/types.h> as well, but we plan to
 remove this soon. To use "makedev", include <sys/sysmacros.h>
 directly. If you did not intend to use a system-defined macro
 "makedev", you should undefine it after including <sys/types.h>. [-Werror]
   if (mknod("/dev/ptmx", 0666 | S_IFCHR, makedev(5, 2)) == 0) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

This commit fixes those errors.

travis-ci: success for zdtm: fix '"makedev" is defined by <sys/sysmacros.h>'
Signed-off-by: Adrian Reber <areber@redhat.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Pavel Emelyanov
aa1d24a76f util: Do not leak dup-ed file descriptor
When going daemon criu services ask cr_daemon() to keep
some descriptors open and the routine dup2-s them. The
problem is that the original descriptor is left where it
was and is leaked.

travis-ci: success for util: Do not leak dup-ed file descriptor
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Andrei Vagin
879d6d1e03 test: check non-root shared mounts
The idea of this test is to check non-root shared mounts
which lives in a few shared groups.

v2: fix the link description.

travis-ci: success for test: check non-root shared mounts (rev2)
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2017-01-12 18:28:43 +03:00
Pavel Emelyanov
a48c533536 page-read: Fix maybe_read_page to accept nr
Most of the rest code uses int nr, so ...

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
2016-12-22 17:44:32 +03:00
Mike Rapoport
215d242ad9 pagemap: drop pagemap2iovec and iovec2pagemap
The PagemapEntry and struct iovec are quite interchangeable.
PagemapEntry can be used directly in the few places that converted it to
struct iovec.
The only place that used iovec2pagemap can be switched to open-coded
assignments without really hurting code readability.

travis-ci: success for pagemap: minor cleanups (rev2)
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:55 +03:00
Mike Rapoport
094ba506fe dedup_one_iovec: explicitly pass start and end instead of iovec
travis-ci: success for pagemap: minor cleanups (rev2)
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:55 +03:00
Pavel Emelyanov
4a7947aa79 page-read: Don't let pr->pe remain NULL
CID 172196, issues/233.

The advance method can keep pr->pe NULL while the rest of
the code doesn't count on that.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
2016-12-22 15:06:55 +03:00
Pavel Emelyanov
5d8e80d607 page-read: Remove get_pagemap method
Now it's obsoleted by the advance method.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
2016-12-22 15:06:55 +03:00
Pavel Emelyanov
84f22ae101 page-read: Remove iov from get_pagemap
We have pr->pe with the same data available widely, no need
to copy this thing twice.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
2016-12-22 15:06:54 +03:00
Mike Rapoport
75b4aae5dc pagemap: replace seek_page with seek_pagemap method
The only external users of ->seek_page method are page-xfer and uffd and
both of them are anyway interested in the entire pagemap rather than a
particular page.
The added 'skip_zero' parameter allows proper detection of zero pagemaps by
uffd.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:54 +03:00
Mike Rapoport
7d929d2d73 dedup, uffd: remove -1 handling for seep_pagemap_page return value
The return value of seep_pagemap_page can be either 1 (page found) or 0 (no
page found). There's no point in checking its return value for -1.

Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:54 +03:00
Mike Rapoport
a1601d9a7d criu: pagemap: make advance a public method
travis-ci: success for uffd: A new set of improvements
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:54 +03:00
Mike Rapoport
11675c71d1 criu: pagemap: don't traverse the entire pagemap while seeking a page
Since commit 95009c4c6d5 (criu: pagemap: introduce advance() helper for
pagemap iteration) seek_pagemap_page traverses the entire pagemap, rather
than starts each time from the last pagemap that was used.
With large pagemaps (like, e.g. in maps05 case) the new behavior causes
exponential increase in amount of calls to skip_pagemap_page for every new
snapshot.
Let's restore the original behavior.

Fixes: #217

Reported-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:54 +03:00
Mike Rapoport
70b072d488 criu: pagemap: introduce advance() helper for pagemap iteration
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-22 15:06:54 +03:00
Pavel Emelyanov
eba074c0e1 arch: Split get_task_regs() into get_ and save_ parts
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 13:14:10 +03:00
Andrei Vagin
b84d2b786c zdtm.py: pass a test PID into zdtm hooks
travis-ci: success for series starting with [01/21] build: install libnet-dev
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 12:37:29 +03:00
Vitaly Ostrosablin
a7faf367a6 test: Fix sockets03 default SIGPIPE handler not being set to IGN
By default, sockets03 doesn't set SIGPIPE handler to SIG_IGN. When run
by zdtm.py, it doesn't cause problem, because it inherits signal
handler. However, when run via vzt-cpt (which uses system() to launch
tests), it receives default handler (which would terminate test). As
result, test is guaranteed to fail, because it will attempt to write to
shutdown receiver and get SIGPIPE in the face.

travis-ci: success for test: Fix sockets03 default SIGPIPE handler not being set to IGN (rev2)
Acked-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Vitaly Ostrosablin <vostrosablin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:03 +03:00
Kirill Tkhai
924a9448c7 zdtm: Add binfmt_misc.hook
A hook to cleanup test temporary files

travis-ci: success for zdtm: Add binfmt_misc.hook
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:03 +03:00
Kirill Tkhai
6f413a5108 scripts: Print error value in case of action script fail
For easier debugging.

v2: Forward scripts messages to criu log using cr_system

travis-ci: success for scripts: Print error value in case of action script fail (rev2)
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:03 +03:00
Kirill Tkhai
7cb248ee2c zdtm: Add sock_peercred test
Check that SO_PEERCRED socket options restored correctly.
Now it's not supported, thus test is marked as "noauto".

(It seems support of this feature will require "ghost tasks",
when we introduce them).

travis-ci: success for zdtm: Add sock_peercred test
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:03 +03:00
Andrei Vagin
0c675a5e9d files: remove link_remaps when everything has been restored
Now we remove a link_remap file when all its files are restored.
It is wrong, because something else may fail and we will not be
able to repeat an attempt to restore processes again.

travis-ci: success for files: remove link_remaps when everything has been restored
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
9c26bae05a fault: check link_remaps if the restore fails at the last moment
link-remap files has to be deleted only if processes have been
restored successfully. Otherwise we can want to repeat an attempt,
but it is imposible if some link-remap files were deleted.

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
f85a04481a test: execute mntns_ghost and mntns_link_remap in userns
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
ef46344f15 files: create links with uid and gid which are known in userns
Starting with 4.8 the kernel doesn't allow to create inodes
with a uid or gid unknown to an user namespace where a file
system was mounted.
036d523641c66 ("vfs: Don't create inodes with a uid or gid unknown to the vfs")

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Kir Kolyshkin
3ed868b3c3 Makefile.install: DESTDIR should be empty
DESTDIR is mostly used by packagers (such as from rpm spec
or deb rules), or just to try installation, and normally
should be left unset/empty.

Setting it to / looks weird to me. Besides, by leaving it empty
we are making sure everything works if DESTDIR is not set.

Fix INSTALL.md accordingly.

travis-ci: success for Makefile.install: DESTDIR should be empty
CC: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
ff728932e3 zdtm.py: add a test name into a progress line
Now it is impossible to find when a test has been started,
but sometimes we want to knwo which tests were running in a specified moment.

travis-ci: success for zdtm.py: add a test name into a progress line
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
db1a0d30b3 zdtm: exit a test if the "root" process died
Each test has a process which controls other processes and
if it dies the other processes have to be killed.

travis-ci: success for zdtm: exit a test if the "root" process died
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Andrei Vagin
3bdcd52f4e files: don't leak a socket in error cases
CID 173074 (#1 of 1): Resource leak (RESOURCE_LEAK)
9. leaked_handle: Handle variable sock going out of scope leaks the handle.

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Dmitry Safonov
65d79e9482 util: use PROC_SELF in vaddr_to_pfn() for open_proc()
Just a little optimization (one syscall less).

travis-ci: success for Rectify 32-bit compatible C/R on x86
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Pavel Emelyanov
9fe7ccca6e py: Fix resp.errno access
There's no such field in resp, only cr_errno

travis-ci: success for py: Fix resp.errno access
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Acked-by: Andrei Vagin <avagin@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Kirill Tkhai
36e43e20fd files: Use collect_gen_fd() in tty_collect_fd()
No functional changes; this just improves uniformity.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:02 +03:00
Kirill Tkhai
c7eeef23e4 files: Create per-process transport sock and bind it
This will be used instead of currently existing per-fd
transport sockets, which are used on receive_fd stage.

v2: Create the socket before CR_STATE_FORKING state.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:23:00 +03:00
Cyrill Gorcunov
d647f47f20 criu: install -- Make INCLUDEDIR not carry criu directory
INCLUDEDIR gonna be used in compel.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
2016-12-21 11:22:24 +03:00