Commit e76749b7 authored by Ruslan Kuprieiev's avatar Ruslan Kuprieiev Committed by Pavel Emelyanov

cr-restore: set cr_error to EEXIST if such pid already exists, v3

This is a very common error when using criu.

The problem here is that we need to somehow transfer cr_errno
from one process to another. I suggest using pipe to give
one end to children and read cr_errno on other after restore
is finished.

v2, Pavel suggested putting errno into shared task_entries.
v3. and he also suggested using cmpxchg
Signed-off-by: 's avatarRuslan Kuprieiev <kupruser@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b09a88b5
...@@ -84,6 +84,9 @@ ...@@ -84,6 +84,9 @@
#include "protobuf/siginfo.pb-c.h" #include "protobuf/siginfo.pb-c.h"
#include "asm/restore.h" #include "asm/restore.h"
#include "asm/atomic.h"
#include "cr-errno.h"
static struct pstree_item *current; static struct pstree_item *current;
...@@ -858,6 +861,9 @@ static inline int sig_fatal(int sig) ...@@ -858,6 +861,9 @@ static inline int sig_fatal(int sig)
struct task_entries *task_entries; struct task_entries *task_entries;
static unsigned long task_entries_pos; static unsigned long task_entries_pos;
#define set_task_cr_err(new_err) atomic_cmpxchg(&task_entries->cr_err, 0, new_err)
#define get_task_cr_err() atomic_read(&task_entries->cr_err)
static int restore_one_zombie(int pid, CoreEntry *core) static int restore_one_zombie(int pid, CoreEntry *core)
{ {
int exit_code = core->tc->exit_code; int exit_code = core->tc->exit_code;
...@@ -1418,6 +1424,7 @@ static int restore_task_with_children(void *_arg) ...@@ -1418,6 +1424,7 @@ static int restore_task_with_children(void *_arg)
pid = getpid(); pid = getpid();
if (current->pid.virt != pid) { if (current->pid.virt != pid) {
pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt); pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
set_task_cr_err(EEXIST);
goto err; goto err;
} }
...@@ -1541,8 +1548,10 @@ static int restore_wait_inprogress_tasks() ...@@ -1541,8 +1548,10 @@ static int restore_wait_inprogress_tasks()
futex_wait_while_gt(np, 0); futex_wait_while_gt(np, 0);
ret = (int)futex_get(np); ret = (int)futex_get(np);
if (ret < 0) if (ret < 0) {
set_cr_errno(get_task_cr_err());
return ret; return ret;
}
return 0; return 0;
} }
......
...@@ -7,6 +7,7 @@ int get_cr_errno(void); ...@@ -7,6 +7,7 @@ int get_cr_errno(void);
/* /*
* List of symbolic error names: * List of symbolic error names:
* ESRCH - no process can be found corresponding to that specified by pid * ESRCH - no process can be found corresponding to that specified by pid
* EEXIST - process with such pid already exists
*/ */
#endif /* __CR_ERRNO_H__ */ #endif /* __CR_ERRNO_H__ */
...@@ -10,6 +10,7 @@ struct task_entries { ...@@ -10,6 +10,7 @@ struct task_entries {
futex_t nr_in_progress; futex_t nr_in_progress;
futex_t start; futex_t start;
mutex_t zombie_lock; mutex_t zombie_lock;
atomic_t cr_err;
}; };
struct fdt { struct fdt {
......
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