mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-28 12:36:47 +00:00
restore: Tune up the resident code to restore threads via last-pid concept
v2: - Pavel reported there is no need to lock/unlock last-pid file in cycle, just lock it once before threads creation and unlock at the end. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
20b0e29698
commit
fa28f40aaa
4 changed files with 76 additions and 4 deletions
|
|
@ -1552,6 +1552,10 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
|||
|
||||
rst_mutex_init(&task_args->rst_lock);
|
||||
|
||||
strncpy(task_args->ns_last_pid_path,
|
||||
LAST_PID_PATH,
|
||||
sizeof(task_args->ns_last_pid_path));
|
||||
|
||||
if (pstree_entry.nr_threads) {
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct cr_fd_desc_tmpl {
|
|||
#define FMT_FNAME_SIGACTS "sigacts-%d.img"
|
||||
|
||||
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
|
||||
#define LAST_PID_PERM 0666
|
||||
|
||||
/* file descriptors */
|
||||
struct cr_fd_desc {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,11 @@ struct task_restore_core_args {
|
|||
int pid; /* task pid */
|
||||
int fd_core; /* opened core file */
|
||||
int fd_self_vmas; /* opened file with running VMAs to unmap */
|
||||
char self_vmas_path[64]; /* path to it, to unlink it once we're done */
|
||||
union {
|
||||
char self_vmas_path[64]; /* path to it, to unlink it once we're done */
|
||||
char last_pid_buf[64]; /* internal buffer to save stack space */
|
||||
};
|
||||
char ns_last_pid_path[64];
|
||||
bool restore_threads; /* if to restore threads */
|
||||
rst_mutex_t rst_lock;
|
||||
|
||||
|
|
@ -231,6 +235,37 @@ static void always_inline write_num_n(long num)
|
|||
sys_write(1, &c, 1);
|
||||
}
|
||||
|
||||
static long always_inline vprint_num(char *buf, long num)
|
||||
{
|
||||
unsigned long d = 1000000000000000000;
|
||||
unsigned int started = 0;
|
||||
unsigned int minus = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int c;
|
||||
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
buf[i++] = '-';
|
||||
}
|
||||
|
||||
while (d) {
|
||||
c = num / d;
|
||||
num -= d * c;
|
||||
d /= 10;
|
||||
if (!c && !started)
|
||||
continue;
|
||||
if (!started)
|
||||
started = 1;
|
||||
add_ord(c);
|
||||
buf[i++] = c;
|
||||
|
||||
}
|
||||
|
||||
buf[i++] = 0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void always_inline write_hex_n(unsigned long num)
|
||||
{
|
||||
unsigned char *s = (unsigned char *)#
|
||||
|
|
|
|||
38
restorer.c
38
restorer.c
|
|
@ -31,6 +31,14 @@ long restore_thread(long cmd, struct thread_restore_args *args)
|
|||
struct core_entry *core_entry;
|
||||
struct rt_sigframe *rt_sigframe;
|
||||
unsigned long new_sp, fsgs_base;
|
||||
int my_pid = sys_gettid();
|
||||
|
||||
if (my_pid != args->pid) {
|
||||
write_num_n(__LINE__);
|
||||
write_num_n(my_pid);
|
||||
write_num_n(args->pid);
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
||||
core_entry = (struct core_entry *)&args->mem_zone.heap;
|
||||
|
||||
|
|
@ -413,10 +421,24 @@ self_len_end:
|
|||
if (args->nr_threads) {
|
||||
struct thread_restore_args *thread_args = args->thread_args;
|
||||
long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND |
|
||||
CLONE_THREAD | CLONE_SYSVSEM |
|
||||
CLONE_CHILD_USEPID;
|
||||
CLONE_THREAD | CLONE_SYSVSEM;
|
||||
long last_pid_len;
|
||||
long parent_tid;
|
||||
int i;
|
||||
int i, fd;
|
||||
|
||||
fd = sys_open(args->ns_last_pid_path, O_RDWR, LAST_PID_PERM);
|
||||
if (fd < 0) {
|
||||
write_num_n(__LINE__);
|
||||
write_num_n(fd);
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
||||
ret = sys_flock(fd, LOCK_EX);
|
||||
if (ret) {
|
||||
write_num_n(__LINE__);
|
||||
write_num_n(ret);
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
||||
for (i = 0; i < args->nr_threads; i++) {
|
||||
|
||||
|
|
@ -430,6 +452,9 @@ self_len_end:
|
|||
RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
|
||||
sizeof(thread_args[i].mem_zone.stack));
|
||||
|
||||
last_pid_len = vprint_num(args->last_pid_buf, thread_args[i].pid - 1);
|
||||
sys_write(fd, args->last_pid_buf, last_pid_len);
|
||||
|
||||
/*
|
||||
* To achieve functionality like libc's clone()
|
||||
* we need a pure assembly here, because clone()'ed
|
||||
|
|
@ -476,6 +501,13 @@ self_len_end:
|
|||
"g"(&thread_args[i])
|
||||
: "rax", "rdi", "rsi", "rdx", "r10", "memory");
|
||||
}
|
||||
|
||||
ret = sys_flock(fd, LOCK_UN);
|
||||
if (ret) {
|
||||
write_num_n(__LINE__);
|
||||
write_num_n(ret);
|
||||
goto core_restore_end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue