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

433 Commits

Author SHA1 Message Date
Pavel Emelyanov
ffacd0f17c image: Open images via openat
Using absolute paths for this is dangerous - while doing c/r we should
be extremely carefully and not change tasks' roots and mount namespaces
too early. Sometimes it will not work -- when restoring containers we'll
be unable to switch to new CT and still have the ability to open images.

Rework the images opening via openat and keep the image dir fd open all
the time as the service fd (introduced earlier).

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2012-03-16 20:45:50 +04:00
Andrey Vagin
adce8197c4 crtools: don't redeclarate the variable
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2012-03-16 15:26:23 +04:00
Cyrill Gorcunov
ea1ec9f619 restore: Don't close pstree_fd several times
There is a scenario when pstree_fd may be tried
to close several times -- if we start crtools
with "detach" option.

So simply make restore_root_task to close opened
file descriptor, this also simplifies the code.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2012-03-07 18:31:20 +04:00
Cyrill Gorcunov
644e4fec6b restore: Don't close LAST_PID_PATH descriptor if it was not opened
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
2012-03-06 17:02:57 +04:00
Cyrill Gorcunov
351537c4f4 cr-restore: Fix typo in restorer_get_vma_hint
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-03-02 23:21:51 +04:00
Pavel Emelyanov
85f18ef02f restorer: Pass self-vmas via memory, not temp file
Reserve more mem for bootrstrap code and put all self vmas at its tail.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-03-02 21:31:35 +04:00
Pavel Emelyanov
471d3c429c restore: Cleanup mem variables usage
Just prepare the code for smoother further bootstrap areas allocation.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-03-02 21:31:35 +04:00
Pavel Emelyanov
fc225709b0 proc: Make parse_maps return the amount of them found
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-03-02 21:31:35 +04:00
Pavel Emelyanov
e94c85fe6e restorer: Fix bootstrap allocation
There are three bugs in this code.

1. self vmas list is released before get-hint is called
2. get-hint code wrongly detects the hole (just bugs, no details)
3. exec hint is mapped without MAP_FIXED, but should

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-03-02 21:31:35 +04:00
Cyrill Gorcunov
7aa8e4b6e2 log: log-engine slight redesign
The messages are filtered by their type

    LOG_MSG     - plain messages, they escape any (!) log level
                  filtration and go to stdout
    LOG_ERROR   - error messages
    LOG_WARN    - warning messages
    LOG_INFO    - informative messages
    LOG_DEBUG   - debug messages

By default the LOG_WARN log level is used, thus LOG_INFO
and LOG_DEBUG messages will not appear in output stream.

pr_panic helper was replaced with pr_err, pr_warning
shorthanded to pr_warn and old printk if rather pr_msg
now.

Because we share messages between "show" and "dump" actions,
before the "show" action proceed we need to tune up
log level and set it to LOG_INFO.

Also note that printing of VMA and siginfo now
became LOG_INFO messages, it was not that correct
to print them regardless the log level.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-03-02 01:05:43 +04:00
Kinsbursky Stanislav
46535130c6 restore: UNIX sockets queue support
Based on xemul@ patches.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-29 17:42:30 +04:00
Kinsbursky Stanislav
eeed250dc3 restore: close opened fd
This is a cleanup patch.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-29 14:46:42 +04:00
Cyrill Gorcunov
8b187454b4 files: Rename prepare_fdinfo_global to prepare_shared_fdinfo
This function simply allocates shared memory. Name it so
and move it closer to the variables it referes on.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-28 19:13:47 +04:00
Cyrill Gorcunov
5cadfef1c1 restore: Add a comment about stack size used in restore procedure
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-28 19:13:47 +04:00
Cyrill Gorcunov
6a0b94e7d5 restore: Don't leak opened file descriptor in shmem_remap
Don't forget to close opened file in case of error.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-20 14:23:27 +04:00
Cyrill Gorcunov
85235af889 restore: Use %lx for map_files
map_files format defined as %lx-%lx in
kernel and while there should not be a
problem if it's written in %p-%p, still
better to be on a safe side and follow
kernel's notation.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-20 14:23:27 +04:00
Kir Kolyshkin
447388d79b open_proc() and friends: hide pid_dir
This patch tries to introduce lazy and hidden pid_dir support,
meaning one don't have to worry about pid_dir but the optimization
is still there.

The patch relies on the fact that we work with many /proc/pid files for
one pid, then for another pid and so on, i.e. not in a random manner.

The idea is when we call open_proc() with a new pid for the first time,
the appropriate /proc/PID directory is opened and its fd is stored.
Next call to open_proc() with the same PID only need to check that
the PID is not changed. In case PID is changed, we close the old one
and open/store a new one.

Now the code using open_proc() and friends:
- does not need to carry proc_pid around, pid is enough
- does not need to call open_pid_proc()

The only thing that can't be done in that "lazy" mode is closing the last
PID fd, thus close_pid_proc().

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-17 16:46:25 +04:00
Kinsbursky Stanislav
574302bf8d restore: support SYSV IPC vma
This patch introduces the following changes:
1) writing of shmid value into vma_area->fd instead of
   waiting for shared memory region is open by parent,
   reopen it and dump fd.
2) new syscall support: sys_shmat
3) use sys_shmat() to map memory region in restorer's
   mapping function if vma flag VMA_AREA_SYSVIPC is set.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-15 13:30:34 +04:00
Kinsbursky Stanislav
a5c6c02f49 restore: shmid_id structure from find_shmem_id() function
Returning shmid value of not enough, because SYSV IPC shmid equal to zero is a
valid value.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-15 13:30:34 +04:00
Kinsbursky Stanislav
e999e9fa29 restore: fix "zobie" typo
Signed-off-by: Stanislav Kinsbursky <skinsbursky@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-14 21:13:33 +04:00
Pavel Emelyanov
227f177194 cr: Split dumped pages locations
This actually does two things:

1. The parasite code writes to pages _or_ to pages_shared file himself based
   on a hint given from the main program. This avoids shared pages copying
   in finalize_core.

2. The private pages are moved out of the core file into a separate one. This
   avoids private pages copying in finalize_core.

The goal of this patch is a) to avoid pages copying at all (we still have
one on restore, but fixing this requires Andrey's work on shared memory
dumping) and b) make big blobs with pages be stored in separate files (I
have plans on its format rework and unification).

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-12 11:45:29 +04:00
Pavel Emelyanov
717994a4fd restore: Don't parse pstree twice
This file is parsed once to find who to fork and then for the 2nd
time to find threads to create.

Remove the 2nd parse holding the info found on the 1st stage in
local *me variable.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-10 20:29:21 +04:00
Cyrill Gorcunov
76a249282e restore: Add checkpoint/restore for /proc/pid/exe symlink
This patch adds ability to checkpoint/restore
/proc/pid/exe symlink, so if a process we've just
checkpointed has been say /path/to/exe, then at restore
time we bring this path back.

There some restiction from kernel side: if
existing /proc/pid/exe already mapped more than
once, the kernel will refuse to change the symlink,
so we need to restore it lately when mmaps of crtools
itself already unmapped (ie via late call in
restorer.c).

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-02-07 20:08:01 +04:00
Andrey Vagin
e5929ab971 restore: sync threads
Use the save mechanosm as for processes.

* Threads should starts together with processes
* If a thread segfaulted, we should be able to detect it.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-02 20:45:54 +04:00
Andrey Vagin
27b20dfcc6 restore: clean up code, which synchronizes resume of tasks (v2)
I added two mechanism of synchronization. The second one is better.
This patch deletes the first one.

Before we had an entry (pid and lock) for each tasks and all this
entries were shared between all processes. Now we don't need "lock"
and we use pids from crtools to kill all processes if someone failed.

v2: s/malloc/xmalloc

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-02 20:45:43 +04:00
Andrey Vagin
3f614e4498 restore: fix length of spliced data
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 17:17:58 +04:00
Cyrill Gorcunov
229defc928 Make sure no uninitialized values are used
I've got it if -O2 compilation option used.

 | cr-restore.c:1069:5: error: ‘ret’ may be used uninitialized in this function [-Werror=uninitialized]
 | sockets.c:1145:7: error: ‘sk’ may be used uninitialized in this function [-Werror=uninitialized]

In first case 'ret' indeed might be uninitialized, and
in second case "goto err" was called too early. Fix them both.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 15:24:39 +04:00
Kir Kolyshkin
1408ead858 Assorted trivial message fixes
* kid -> child
* First letter should be uppercase
* Misc typos in messages and comments

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-02-01 02:55:16 +04:00
Stanislav Kinsbursky
0213d3ec64 namespaces: parametrized namespace option introduced
v2: strlen() check removed from parse_ns_string()

Now '-n' option must be followed by namespaces tags, separated by commas.
Currently, only "uts" namespace is supported.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-31 22:32:22 +04:00
Kir Kolyshkin
9e08244291 cr-restore.c: fix printf format warnings
cr-restore.c: In function ‘fixup_vma_fds’:
cr-restore.c:578:4: error: format ‘%d’ expects type ‘int’, but argument 6 has type ‘long unsigned int’
cr-restore.c: In function ‘sigreturn_restore’:
cr-restore.c:1693:4: error: format ‘%li’ expects type ‘long int’, but argument 4 has type ‘int’
cr-restore.c:1738:3: error: format ‘%d’ expects type ‘int’, but argument 4 has type ‘long int’
cr-restore.c:1751:3: error: format ‘%d’ expects type ‘int’, but argument 4 has type ‘long int’
cr-restore.c:1755:3: error: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long int’
cr-restore.c:1868:4: error: format ‘%8p’ expects type ‘void *’, but argument 3 has type ‘long int’

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-31 15:56:42 +04:00
Kir Kolyshkin
0b237ae9f2 pr_perror(): print error at the end of line
This is a standard convention to print error message (i.e. strerror(errno))
at the end of line, like this:

        Cannot remove file: Permission denied

So pr_perror is fixed to follow this convention (using GNU extension
%m helps a lot here). Unfortunately, due to this we have to make
pr_perror() print a new line character, too, so we had to strip it
from the all pr_perror() invocations.

That (appending a newline) also makes pr_perror() a black sheep
in the herd of pr_* helpers, but what can we do? Worst case scenario
is an extra newline after an error message, not too harmful.

An alternative approach (stripping the newline from the passed format
string and re-adding it) was discussed thoroughly, and it was decided
that such a hack looks a bit too dirty.

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-31 15:49:15 +04:00
Kir Kolyshkin
8a6269e490 restore_pipe_data(): fix a typo
Found using clang:

cr-restore.c:796:8: error: use of unary operator that may be intended as compound assignment (+=)
                size =+ ret;
                     ^~

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-31 13:05:29 +04:00
Konstantin Khlebnikov
be6a7feae7 cr: reuse zero_page_entry in fixup_pages_data
fix compilation error:
cr-restore.c:621:13: error: variably modified ‘zpage’ at file scope

Signed-off-by: Konstantin Khlebnikov <khlebnikov@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-30 23:03:27 +04:00
Cyrill Gorcunov
4a7764c5ee restore: Make sure exit_code is < 128
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@openvz.org>
2012-01-30 17:39:20 +04:00
Pavel Emelyanov
beb158a66e cr: Task creds support
Dumping is simple. All but secbits can be read from proc, secbits
are got from parasite.

Restoring is a bit tricky -- when you change anything on kernel
cred's struct it performs sophisticated checks and can change
some more stuff than requested, so the creds restoration procedure
is carefully commented step-by-step.

Another thing to mention is that creds are restored after everything
else, i.e. right before performing final threads sync and sigreturns.
This is done to avoid potential problems with insufficient caps for
restoring other stuff (e.g. CAP_DAC_OVERRIDE or zero euid is most
likely required for opening any image file and the notorious control
/proc/sys/kernel/ns_last_pid, which in turn is performed till the
very last moment).

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-30 13:00:50 +04:00
Pavel Emelyanov
4804db00aa restore: Switch code to new R/W API
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-28 23:55:50 +04:00
Stanislav Kinsbursky
6e0353badc restore: missed carriage return added
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Acked-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-27 20:18:26 +04:00
Cyrill Gorcunov
d4cfba8947 restore: Bring original SIGCHLD handler back once task is restored
Otherwise if restored task exit we get error message in form

 | Error (cr-restore.c:1302): 7244 exited, status=0

while restored task simply finished working.

Pointed-out-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
2012-01-27 12:39:42 +04:00
Pavel Emelyanov
98f4c2e4de ns: Support UTS namespace
Only two fields are modifiable -- hostname and domainname. So
read them on dump and write on restore.

File format is simple --

u32 magic
u32 length of nodename
u8[] nodename string
u32 length of domainname
u8[] domainname string

For OpenVZ we can write the release at the end, but this is later.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-26 16:54:22 +04:00
Pavel Emelyanov
3391416a1b crtools: Namespaces support skeleton
New option -n to dump/restore namespaces.

Fork the namespaces dumping task and write a helper for switching a namespace.

Prepare the restorer code for restoring namespaces before root task.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-26 16:54:22 +04:00
Pavel Emelyanov
b5e5aac9e9 restore: Switch task fork-ing into clone-ing
In order to restore task in namespaces we'll have to clone() them,
not fork. Thus switch the restorer into using clone.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-26 16:54:22 +04:00
Pavel Emelyanov
2e48f0528b crtools: Move options deeper into the code
I will need them in the place where we restore the root task.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-26 16:54:22 +04:00
Pavel Emelyanov
b7de83aaf3 crtools: Interval timers support
Timers are dumped from inside parasite code, the format is plain -- just
3 pairs of interval/value one-by-one.

The restoration occurs in two stages -- first prepare the timer values in
restorer (and check for sanity), then setup the timers in the latest stage
before actually calling the sigreturn.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-24 18:41:49 +04:00
Pavel Emelyanov
5c2083ee87 cr: Support zombie tasks
Dump the core-pid.img file only. On restore select the way of killing
task based on his exit_code -- exit or kill with a signal. Before dying
unblock all the handlers and set SIG_DFL to it (to make the dead signal
other than KILL be deliverable).

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-23 01:44:01 +04:00
Pavel Emelyanov
3822c079c4 restore: Ignore ENOENT when preparing shared resources
The absent image file on shared resources preparation now means -- no resources
for this pid (zombies will not have these files).

This is not the most elegant solution, but I don't have anything better in mind.
Need to think over, all the more so we're most likely about to reimplement the
way image is stored some day in the future.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-23 01:43:53 +04:00
Pavel Emelyanov
164ccc095f crtools: R/W API rewrite
Kill all the macros for reading/writing image parts. New API looks like

* write_img_buf/write_img
  Write an object into an image. Reports 0 for OK, -1 for error. The _buf
  version accepts object size as an argument, the other one uses sizeof()

* read_img_buf/read_img
  Reads an object from image. Reports 0 for OK, -1 for error or EOF.

* read_img_buf_eof/read_img
  Reads an object from image. Reports 1 for OK, 0 for EOF and -1 for error.
  This is not symmetrical with the previous one, but it was done deliberately
  to make it possible to write code like

  ret = read_img_bug_eof();
  if (ret <= 0)
	return ret; /* 0 means OK, all is done, -1 means error was met */.

  ... /* 1 means object was read, can proceed */

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-23 01:43:10 +04:00
Cyrill Gorcunov
48f624ee17 restore: Drop real_pid member from shmem_info structure
It's not needed anymore, it was handing cases
where no fork-with-pid functionality were in
kernel, but now it's simply unneeded.

Also drop redundant getpid() calls.

Passes all tests (except fork test which known to fail).

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parllels.com>
2012-01-20 13:08:06 +04:00
Pavel Emelyanov
6128b88c76 restorer: Use LAST_PID_PATH directly
After Andrey's work with making restorer a regular .o file we can do it
(the pthread00 test doesn't fail on it).

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-19 22:41:32 +04:00
Andrey Vagin
1dd20b087a restore: detect that someone failed (v2)
Handle SIGCHLD and if someone failed, nr_in_progress is set to -1.
If crtools notices that nr_in_progress is negative, it kills all
tasks.

v2: * Use named constants for task_entries->start in restorer.c
    * Use SA_NOCLDWAIT when setting sigchild handler,
      this makes sigchild handler simpler.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-19 16:16:58 +04:00
Andrey Vagin
99498681e6 restore: new mechanism to sync tasks
Now we have only one mutex nr_in_progress, it says how many
tasks are not restored yet. A negative value signs that someone
failed.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
Acked-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
2012-01-19 16:16:58 +04:00