From acf604c60c49fce31221f446e15f474069a45d00 Mon Sep 17 00:00:00 2001 From: Kinsbursky Stanislav Date: Tue, 21 Feb 2012 12:10:36 +0300 Subject: [PATCH] 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: Stanislav Kinsbursky Acked-by: Pavel Emelyanov Signed-off-by: Cyrill Gorcunov --- restorer.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/restorer.c b/restorer.c index ea4af0403..552f74137 100644 --- a/restorer.c +++ b/restorer.c @@ -722,6 +722,9 @@ long restore_task(struct task_restore_core_args *args) sys_sigaction(SIGCHLD, &args->sigchld_act, NULL); cr_wait_dec(&args->task_entries->nr_in_progress); + + sys_close(args->logfd); + cr_wait_while(&args->task_entries->start, CR_STATE_RESTORE_SIGCHLD); /* @@ -742,13 +745,10 @@ long restore_task(struct task_restore_core_args *args) ret = sys_munmap(args->task_entries, TASK_ENTRIES_SIZE); if (ret < 0) { - write_num_n(__LINE__); - write_num_n(ret); - goto core_restore_end; + ret = ((long)__LINE__ << 32) | -ret; + goto core_restore_failed; } - sys_close(args->logfd); - /* * Sigframe stack. */ @@ -773,4 +773,14 @@ core_restore_end: write_num_n(sys_getpid()); sys_exit(-1); return -1; + +core_restore_failed: + asm volatile( + "movq %0, %%rsp \n" + "movq 0, %%rax \n" + "jmp *%%rax \n" + : + : "r"(ret) + : ); + return ret; }