Commit acf604c6 authored by Kinsbursky Stanislav's avatar Kinsbursky Stanislav Committed by Cyrill Gorcunov

restorer: close log file before detaching from crtools

v2: it's toom risky to jump to address equal to line numbet (there could be
valid executable code). So now jump is done to 0 address and %sp encodes line
number (32 most significant bits) and error code (32 least significant bits).

There is a race between log close by process being restoring and opened file
desctriptors check in zdtm test suite - crtools can exit and compare file
descriptors before detached restored process will perform all the rest tasks
(including close of the log) and execute final system call:

 |--- dump/sleeping00/8578/dump.fd        2012-02-20 14:31:31.246096000 +0300
 |+++ dump/sleeping00/8578/restore.fd     2012-02-20 14:31:31.418095999 +0300
 |@@ -1,4 +1,5 @@
 |
 | 0 -> /dev/null
 | 1 -> /dev/null
 |+1023 -> /root/crtools/test/dump/sleeping00/8578/restore.log
 | 2 -> /dev/null

The solution is to close log in restorer before final command received. But
this leads to another problem: we have to inform somehow about possible errors
afterwards This is done by forced segmentation fault and looks like this
(dmesg):

pipe00[4678]: segfault at 0 ip 00007f4c8ab77d02 sp 000002ed00000001 error 4

Where %sp encodes line number (32 most significant bits) and error code (32
least significant bits).
Signed-off-by: 's avatarStanislav Kinsbursky <skinsbursky@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 7f96ec68
...@@ -722,6 +722,9 @@ long restore_task(struct task_restore_core_args *args) ...@@ -722,6 +722,9 @@ long restore_task(struct task_restore_core_args *args)
sys_sigaction(SIGCHLD, &args->sigchld_act, NULL); sys_sigaction(SIGCHLD, &args->sigchld_act, NULL);
cr_wait_dec(&args->task_entries->nr_in_progress); cr_wait_dec(&args->task_entries->nr_in_progress);
sys_close(args->logfd);
cr_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD); cr_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD);
/* /*
...@@ -742,13 +745,10 @@ long restore_task(struct task_restore_core_args *args) ...@@ -742,13 +745,10 @@ long restore_task(struct task_restore_core_args *args)
ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE); ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE);
if (ret < 0) { if (ret < 0) {
write_num_n(__LINE__); ret = ((long)__LINE__ << 32) | -ret;
write_num_n(ret); goto core_restore_failed;
goto core_restore_end;
} }
sys_close(args->logfd);
/* /*
* Sigframe stack. * Sigframe stack.
*/ */
...@@ -773,4 +773,14 @@ core_restore_end: ...@@ -773,4 +773,14 @@ core_restore_end:
write_num_n(sys_getpid()); write_num_n(sys_getpid());
sys_exit(-1); sys_exit(-1);
return -1; return -1;
core_restore_failed:
asm volatile(
"movq %0, %%rsp \n"
"movq 0, %%rax \n"
"jmp *%%rax \n"
:
: "r"(ret)
: );
return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment