diff --git a/cr-restore.c b/cr-restore.c index f7887fd82..c8a616d33 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -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; diff --git a/include/crtools.h b/include/crtools.h index 8af27bd4a..e4d9e4a99 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -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 { diff --git a/include/restorer.h b/include/restorer.h index 4a2dec8ee..aa1e38ece 100644 --- a/include/restorer.h +++ b/include/restorer.h @@ -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 *)# diff --git a/restorer.c b/restorer.c index 5154ee2fc..62217be03 100644 --- a/restorer.c +++ b/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; + } } /*