Commit fa28f40a authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

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: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 20b0e296
...@@ -1552,6 +1552,10 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1552,6 +1552,10 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
rst_mutex_init(&task_args->rst_lock); 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) { if (pstree_entry.nr_threads) {
int i; int i;
......
...@@ -55,6 +55,7 @@ struct cr_fd_desc_tmpl { ...@@ -55,6 +55,7 @@ struct cr_fd_desc_tmpl {
#define FMT_FNAME_SIGACTS "sigacts-%d.img" #define FMT_FNAME_SIGACTS "sigacts-%d.img"
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid" #define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
#define LAST_PID_PERM 0666
/* file descriptors */ /* file descriptors */
struct cr_fd_desc { struct cr_fd_desc {
......
...@@ -66,7 +66,11 @@ struct task_restore_core_args { ...@@ -66,7 +66,11 @@ struct task_restore_core_args {
int pid; /* task pid */ int pid; /* task pid */
int fd_core; /* opened core file */ int fd_core; /* opened core file */
int fd_self_vmas; /* opened file with running VMAs to unmap */ 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 */ bool restore_threads; /* if to restore threads */
rst_mutex_t rst_lock; rst_mutex_t rst_lock;
...@@ -231,6 +235,37 @@ static void always_inline write_num_n(long num) ...@@ -231,6 +235,37 @@ static void always_inline write_num_n(long num)
sys_write(1, &c, 1); 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) static void always_inline write_hex_n(unsigned long num)
{ {
unsigned char *s = (unsigned char *)&num; unsigned char *s = (unsigned char *)&num;
......
...@@ -31,6 +31,14 @@ long restore_thread(long cmd, struct thread_restore_args *args) ...@@ -31,6 +31,14 @@ long restore_thread(long cmd, struct thread_restore_args *args)
struct core_entry *core_entry; struct core_entry *core_entry;
struct rt_sigframe *rt_sigframe; struct rt_sigframe *rt_sigframe;
unsigned long new_sp, fsgs_base; 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; core_entry = (struct core_entry *)&args->mem_zone.heap;
...@@ -413,10 +421,24 @@ self_len_end: ...@@ -413,10 +421,24 @@ self_len_end:
if (args->nr_threads) { if (args->nr_threads) {
struct thread_restore_args *thread_args = args->thread_args; struct thread_restore_args *thread_args = args->thread_args;
long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND | long clone_flags = CLONE_VM | CLONE_FILES | CLONE_SIGHAND |
CLONE_THREAD | CLONE_SYSVSEM | CLONE_THREAD | CLONE_SYSVSEM;
CLONE_CHILD_USEPID; long last_pid_len;
long parent_tid; 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++) { for (i = 0; i < args->nr_threads; i++) {
...@@ -430,6 +452,9 @@ self_len_end: ...@@ -430,6 +452,9 @@ self_len_end:
RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack, RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
sizeof(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() * To achieve functionality like libc's clone()
* we need a pure assembly here, because clone()'ed * we need a pure assembly here, because clone()'ed
...@@ -476,6 +501,13 @@ self_len_end: ...@@ -476,6 +501,13 @@ self_len_end:
"g"(&thread_args[i]) "g"(&thread_args[i])
: "rax", "rdi", "rsi", "rdx", "r10", "memory"); : "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;
}
} }
/* /*
......
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