Commit 9d918c59 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

protobuf: Convert core_entry to PB format v5

This requires some exlanations

 - Since we use protobuf data in restorer
   code we need to carry a copy of appropriate
   PB entities in resident memory. For this
   sake task_restore_core_args and thread_restore_args
   were significantly reworked. In short -- the caller
   code fills PB structures into task arguments space.

v3:
 - Combine everything arch related to thread_info field,
   and make it optional
 - Drop "version" field from message, we check version in
   another specific message
 - Don't forget to call core_entry__free_unpacked where needed
 - We continue dumping FPU state, still it's not yet restored

v4:
 - Don't carry task_core_entry and task_kobs_ids_entry for
   threads, and yield error if present in image.

v5:
 - Allocate core_entry depending on type of task being dumped
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 092ae8c9
This diff is collapsed.
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
static struct pstree_item *me; static struct pstree_item *me;
static int restore_task_with_children(void *); static int restore_task_with_children(void *);
static int sigreturn_restore(pid_t pid, struct list_head *vmas, int nr_vmas); static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *vmas, int nr_vmas);
static int shmem_remap(void *old_addr, void *new_addr, unsigned long size) static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
{ {
...@@ -186,7 +186,7 @@ static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas) ...@@ -186,7 +186,7 @@ static int read_and_open_vmas(int pid, struct list_head *vmas, int *nr_vmas)
return ret; return ret;
} }
static int prepare_and_sigreturn(int pid) static int prepare_and_sigreturn(int pid, CoreEntry *core)
{ {
int err, nr_vmas; int err, nr_vmas;
LIST_HEAD(vma_list); LIST_HEAD(vma_list);
...@@ -195,7 +195,7 @@ static int prepare_and_sigreturn(int pid) ...@@ -195,7 +195,7 @@ static int prepare_and_sigreturn(int pid)
if (err) if (err)
return err; return err;
return sigreturn_restore(pid, &vma_list, nr_vmas); return sigreturn_restore(pid, core, &vma_list, nr_vmas);
} }
static rt_sigaction_t sigchld_act; static rt_sigaction_t sigchld_act;
...@@ -276,7 +276,7 @@ static int pstree_wait_helpers() ...@@ -276,7 +276,7 @@ static int pstree_wait_helpers()
} }
static int restore_one_alive_task(int pid) static int restore_one_alive_task(int pid, CoreEntry *core)
{ {
pr_info("Restoring resources\n"); pr_info("Restoring resources\n");
...@@ -292,7 +292,7 @@ static int restore_one_alive_task(int pid) ...@@ -292,7 +292,7 @@ static int restore_one_alive_task(int pid)
if (prepare_sigactions(pid)) if (prepare_sigactions(pid))
return -1; return -1;
return prepare_and_sigreturn(pid); return prepare_and_sigreturn(pid, core);
} }
static void zombie_prepare_signals(void) static void zombie_prepare_signals(void)
...@@ -391,24 +391,19 @@ static int restore_one_zombie(int pid, int exit_code) ...@@ -391,24 +391,19 @@ static int restore_one_zombie(int pid, int exit_code)
return -1; return -1;
} }
static int check_core_header(int pid, struct task_core_entry *tc) static int check_core_header(int pid, CoreEntry *core)
{ {
int fd = -1, ret = -1; int fd = -1, ret = -1;
struct image_header hdr;
fd = open_image_ro(CR_FD_CORE, pid); fd = open_image_ro(CR_FD_CORE, pid);
if (fd < 0) if (fd < 0)
return -1; return -1;
if (read_img(fd, &hdr) < 0) if (core->mtype != CORE_ENTRY__MARCH__X86_64) {
goto out; pr_err("Core march mismatch %d\n", (int)core->mtype);
if (hdr.arch != HEADER_ARCH_X86_64) {
pr_err("Core arch mismatch %d\n", (int)hdr.arch);
goto out; goto out;
} }
ret = 0;
ret = read_img(fd, tc);
out: out:
close_safe(&fd); close_safe(&fd);
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
...@@ -416,23 +411,43 @@ out: ...@@ -416,23 +411,43 @@ out:
static int restore_one_task(int pid) static int restore_one_task(int pid)
{ {
struct task_core_entry tc; int fd, ret;
CoreEntry *core;
if (me->state == TASK_HELPER) if (me->state == TASK_HELPER)
return restore_one_fake(pid); return restore_one_fake(pid);
if (check_core_header(pid, &tc)) fd = open_image_ro(CR_FD_CORE, pid);
if (fd < 0)
return -1; return -1;
switch ((int)tc.task_state) { ret = pb_read(fd, &core, core_entry);
close(fd);
if (ret < 0)
return -1;
if (check_core_header(pid, core)) {
ret = -1;
goto out;
}
switch ((int)core->tc->task_state) {
case TASK_ALIVE: case TASK_ALIVE:
return restore_one_alive_task(pid); ret = restore_one_alive_task(pid, core);
break;
case TASK_DEAD: case TASK_DEAD:
return restore_one_zombie(pid, tc.exit_code); ret = restore_one_zombie(pid, core->tc->exit_code);
break;
default: default:
pr_err("Unknown state in code %d\n", (int)tc.task_state); pr_err("Unknown state in code %d\n", (int)core->tc->task_state);
return -1; ret = -1;
break;
} }
out:
core_entry__free_unpacked(core, NULL);
return ret;
} }
/* /*
...@@ -1117,7 +1132,7 @@ out: ...@@ -1117,7 +1132,7 @@ out:
return ret; return ret;
} }
static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_vmas, int nr_vmas)
{ {
long restore_code_len, restore_task_vma_len; long restore_code_len, restore_task_vma_len;
long restore_thread_vma_len, self_vmas_len, vmas_len; long restore_thread_vma_len, self_vmas_len, vmas_len;
...@@ -1134,7 +1149,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1134,7 +1149,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
struct thread_restore_args *thread_args; struct thread_restore_args *thread_args;
LIST_HEAD(self_vma_list); LIST_HEAD(self_vma_list);
int fd_core = -1;
int fd_pages = -1; int fd_pages = -1;
int i; int i;
...@@ -1159,12 +1173,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1159,12 +1173,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE); BUILD_BUG_ON(SHMEMS_SIZE % PAGE_SIZE);
BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE); BUILD_BUG_ON(TASK_ENTRIES_SIZE % PAGE_SIZE);
fd_core = open_image_ro(CR_FD_CORE, pid);
if (fd_core < 0) {
pr_perror("Can't open core-out-%d", pid);
goto err;
}
fd_pages = open_image_ro(CR_FD_PAGES, pid); fd_pages = open_image_ro(CR_FD_PAGES, pid);
if (fd_pages < 0) { if (fd_pages < 0) {
pr_perror("Can't open pages-%d", pid); pr_perror("Can't open pages-%d", pid);
...@@ -1279,12 +1287,24 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1279,12 +1287,24 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
/* /*
* Arguments for task restoration. * Arguments for task restoration.
*/ */
BUG_ON(core->mtype != CORE_ENTRY__MARCH__X86_64);
task_args->pid = pid; task_args->pid = pid;
task_args->fd_core = fd_core;
task_args->logfd = log_get_fd(); task_args->logfd = log_get_fd();
task_args->sigchld_act = sigchld_act; task_args->sigchld_act = sigchld_act;
task_args->fd_pages = fd_pages; task_args->fd_pages = fd_pages;
strncpy(task_args->comm, core->tc->comm, sizeof(task_args->comm));
task_args->clear_tid_addr = core->thread_info->clear_tid_addr;
task_args->ids = *core->ids;
task_args->gpregs = *core->thread_info->gpregs;
task_args->blk_sigset = core->tc->blk_sigset;
/* No longer need it */
core_entry__free_unpacked(core, NULL);
ret = prepare_itimers(pid, task_args); ret = prepare_itimers(pid, task_args);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -1310,18 +1330,40 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1310,18 +1330,40 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
* Fill up per-thread data. * Fill up per-thread data.
*/ */
for (i = 0; i < me->nr_threads; i++) { for (i = 0; i < me->nr_threads; i++) {
int fd_core;
thread_args[i].pid = me->threads[i].virt; thread_args[i].pid = me->threads[i].virt;
/* skip self */ /* skip self */
if (thread_args[i].pid == pid) if (thread_args[i].pid == pid)
continue; continue;
/* Core files are to be opened */ fd_core = open_image_ro(CR_FD_CORE, thread_args[i].pid);
thread_args[i].fd_core = open_image_ro(CR_FD_CORE, thread_args[i].pid); if (fd_core < 0) {
if (thread_args[i].fd_core < 0) pr_err("Can't open core data for thread %d\n",
thread_args[i].pid);
goto err; goto err;
}
ret = pb_read(fd_core, &core, core_entry);
close(fd_core);
if (core->tc || core->ids) {
pr_err("Thread has optional fields present %d\n",
thread_args[i].pid);
ret = -1;
}
if (ret < 0) {
pr_err("Can't read core data for thread %d\n",
thread_args[i].pid);
goto err;
}
thread_args[i].rst_lock = &task_args->rst_lock;
thread_args[i].gpregs = *core->thread_info->gpregs;
thread_args[i].clear_tid_addr = core->thread_info->clear_tid_addr;
thread_args[i].rst_lock = &task_args->rst_lock; core_entry__free_unpacked(core, NULL);
pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n", pr_info("Thread %4d stack %8p heap %8p rt_sigframe %8p\n",
i, thread_args[i].mem_zone.stack, i, thread_args[i].mem_zone.stack,
...@@ -1334,12 +1376,10 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1334,12 +1376,10 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
pr_info("task_args: %p\n" pr_info("task_args: %p\n"
"task_args->pid: %d\n" "task_args->pid: %d\n"
"task_args->fd_core: %d\n"
"task_args->nr_threads: %d\n" "task_args->nr_threads: %d\n"
"task_args->clone_restore_fn: %p\n" "task_args->clone_restore_fn: %p\n"
"task_args->thread_args: %p\n", "task_args->thread_args: %p\n",
task_args, task_args->pid, task_args, task_args->pid,
task_args->fd_core,
task_args->nr_threads, task_args->nr_threads,
task_args->clone_restore_fn, task_args->clone_restore_fn,
task_args->thread_args); task_args->thread_args);
...@@ -1362,7 +1402,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas) ...@@ -1362,7 +1402,6 @@ static int sigreturn_restore(pid_t pid, struct list_head *tgt_vmas, int nr_vmas)
err: err:
free_mappings(&self_vma_list); free_mappings(&self_vma_list);
close_safe(&fd_core);
/* Just to be sure */ /* Just to be sure */
exit(1); exit(1);
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "protobuf/mm.pb-c.h" #include "protobuf/mm.pb-c.h"
#include "protobuf/vma.pb-c.h" #include "protobuf/vma.pb-c.h"
#include "protobuf/creds.pb-c.h" #include "protobuf/creds.pb-c.h"
#include "protobuf/core.pb-c.h"
#define DEF_PAGES_PER_LINE 6 #define DEF_PAGES_PER_LINE 6
...@@ -51,24 +52,6 @@ ...@@ -51,24 +52,6 @@
#define PR_SYMBOL(sym) \ #define PR_SYMBOL(sym) \
(isprint(sym) ? sym : '.') (isprint(sym) ? sym : '.')
#define pr_regs4(s, n1, n2, n3, n4) \
pr_msg("%8s: 0x%16lx " \
"%8s: 0x%16lx " \
"%8s: 0x%16lx " \
"%8s: 0x%16lx\n", \
#n1, s.n1, \
#n2, s.n2, \
#n3, s.n3, \
#n4, s.n4)
#define pr_regs3(s, n1, n2, n3) \
pr_msg("%8s: 0x%16lx " \
"%8s: 0x%16lx " \
"%8s: 0x%16lx\n", \
#n1, s.n1, \
#n2, s.n2, \
#n3, s.n3)
static LIST_HEAD(pstree_list); static LIST_HEAD(pstree_list);
void show_files(int fd_files, struct cr_options *o) void show_files(int fd_files, struct cr_options *o)
...@@ -370,30 +353,6 @@ void show_pstree(int fd_pstree, struct cr_options *o) ...@@ -370,30 +353,6 @@ void show_pstree(int fd_pstree, struct cr_options *o)
show_collect_pstree(fd_pstree, NULL); show_collect_pstree(fd_pstree, NULL);
} }
static void show_core_regs(int fd_core)
{
struct user_regs_entry regs;
pr_msg("\n\t---[GP registers set]---\n");
lseek(fd_core, GET_FILE_OFF(struct core_entry, arch.gpregs), SEEK_SET);
if (read_img(fd_core, &regs) < 0)
goto err;
pr_regs4(regs, cs, ip, ds, es);
pr_regs4(regs, ss, sp, fs, gs);
pr_regs4(regs, di, si, dx, cx);
pr_regs4(regs, ax, r8, r9, r10);
pr_regs4(regs, r11, r12, r13, r14);
pr_regs3(regs, r15, bp, bx);
pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
pr_msg("\n");
err:
return;
}
static inline char *task_state_str(int state) static inline char *task_state_str(int state)
{ {
switch (state) { switch (state) {
...@@ -406,68 +365,98 @@ static inline char *task_state_str(int state) ...@@ -406,68 +365,98 @@ static inline char *task_state_str(int state)
} }
} }
static void show_core_rest(int fd_core) static void show_core_rest(TaskCoreEntry *tc)
{ {
struct task_core_entry tc; if (!tc)
return;
lseek(fd_core, GET_FILE_OFF(struct core_entry, tc), SEEK_SET); pr_msg("\t---[ Task parameters ]---\n");
if (read_img(fd_core, &tc) < 0) pr_msg("\tPersonality: %#x\n", tc->personality);
goto err; pr_msg("\tCommand: %s\n", tc->comm);
pr_msg("\n\t---[Task parameters]---\n");
pr_msg("\tPersonality: %#x\n", tc.personality);
pr_msg("\tCommand: %s\n", tc.comm);
pr_msg("\tState: %d (%s)\n", pr_msg("\tState: %d (%s)\n",
(int)tc.task_state, (int)tc->task_state,
task_state_str((int)tc.task_state)); task_state_str((int)tc->task_state));
pr_msg("\t Exit code: %u\n", pr_msg("\t Exit code: %u\n",
(unsigned int)tc.exit_code); (unsigned int)tc->exit_code);
pr_msg("\tBlkSig: 0x%lx\n", tc.blk_sigset); pr_msg("\tBlkSig: 0x%lx\n", tc->blk_sigset);
pr_msg("\n"); pr_msg("\n");
}
err: static void show_core_ids(TaskKobjIdsEntry *ids)
return; {
if (!ids)
return;
pr_msg("\t---[ Task IDS ]---\n");
pr_msg("\tVM: %#x\n", ids->vm_id);
pr_msg("\tFS: %#x\n", ids->fs_id);
pr_msg("\tFILES: %#x\n", ids->files_id);
pr_msg("\tSIGHAND: %#x\n", ids->sighand_id);
} }
static void show_core_ids(int fd) static void show_core_regs(UserX86RegsEntry *regs)
{ {
struct core_ids_entry cie; #define pr_regs4(s, n1, n2, n3, n4) \
pr_msg("\t%8s: 0x%-16lx " \
"%8s: 0x%-16lx " \
"%8s: 0x%-16lx " \
"%8s: 0x%-16lx\n", \
#n1, s->n1, \
#n2, s->n2, \
#n3, s->n3, \
#n4, s->n4)
lseek(fd, GET_FILE_OFF(struct core_entry, ids), SEEK_SET); #define pr_regs3(s, n1, n2, n3) \
if (read_img(fd, &cie) < 0) pr_msg("\t%8s: 0x%-16lx " \
goto err; "%8s: 0x%-16lx " \
"%8s: 0x%-16lx\n", \
#n1, s->n1, \
#n2, s->n2, \
#n3, s->n3)
pr_msg("\tVM: %#x\n", cie.vm_id); pr_msg("\t---[ GP registers set ]---\n");
pr_msg("\tFS: %#x\n", cie.fs_id);
pr_msg("\tFILES: %#x\n", cie.files_id); pr_regs4(regs, cs, ip, ds, es);
pr_msg("\tSIGHAND: %#x\n", cie.sighand_id); pr_regs4(regs, ss, sp, fs, gs);
err: pr_regs4(regs, di, si, dx, cx);
return; pr_regs4(regs, ax, r8, r9, r10);
pr_regs4(regs, r11, r12, r13, r14);
pr_regs3(regs, r15, bp, bx);
pr_regs4(regs, orig_ax, flags, fs_base, gs_base);
pr_msg("\n");
}
void show_thread_info(ThreadInfoX86 *thread_info)
{
pr_msg("\t---[ Thread info ]---\n");
pr_msg("\tclear_tid_addr: 0x%lx\n", thread_info->clear_tid_addr);
pr_msg("\n");
show_core_regs(thread_info->gpregs);
} }
void show_core(int fd_core, struct cr_options *o) void show_core(int fd_core, struct cr_options *o)
{ {
struct stat stat; CoreEntry *core;
bool is_thread;
if (fstat(fd_core, &stat)) { pr_img_head(CR_FD_CORE);
pr_perror("Can't get stat on core file"); if (pb_read_eof(fd_core, &core, core_entry) > 0) {
goto out;
}
is_thread = (stat.st_size == GET_FILE_OFF_AFTER(struct core_entry)); pr_msg("\t---[ General ]---\n");
pr_msg("\tmtype: 0x%x\n", core->mtype);
pr_msg("\n");
if (is_thread) /* Continue if we support it */
pr_img_head(CR_FD_CORE, " (thread)"); if (core->mtype == CORE_ENTRY__MARCH__X86_64) {
else show_thread_info(core->thread_info);
pr_img_head(CR_FD_CORE); show_core_rest(core->tc);
show_core_ids(core->ids);
}
show_core_regs(fd_core); core_entry__free_unpacked(core, NULL);
show_core_rest(fd_core); }
show_core_ids(fd_core);
out:
pr_img_tail(CR_FD_CORE); pr_img_tail(CR_FD_CORE);
} }
......
...@@ -87,138 +87,19 @@ struct page_entry { ...@@ -87,138 +87,19 @@ struct page_entry {
#define CR_CAP_SIZE 2 #define CR_CAP_SIZE 2
#define HEADER_ARCH_X86_64 1
struct image_header {
u32 arch;
u32 flags;
} __packed;
/*
* PTRACE_GETREGS
* PTRACE_GETFPREGS
* PTRACE_GETFPXREGS dep CONFIG_X86_32
* PTRACE_GET_THREAD_AREA dep CONFIG_X86_32 || CONFIG_IA32_EMULATION
* PTRACE_GETFDPIC dep CONFIG_BINFMT_ELF_FDPIC
*
* PTRACE_ARCH_PRCTL dep CONFIG_X86_64
* ARCH_SET_GS/ARCH_GET_FS
* ARCH_SET_FS/ARCH_GET_GS
*/
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
struct user_regs_entry {
u64 r15;
u64 r14;
u64 r13;
u64 r12;
u64 bp;
u64 bx;
u64 r11;
u64 r10;
u64 r9;
u64 r8;
u64 ax;
u64 cx;
u64 dx;
u64 si;
u64 di;
u64 orig_ax;
u64 ip;
u64 cs;
u64 flags;
u64 sp;
u64 ss;
u64 fs_base;
u64 gs_base;
u64 ds;
u64 es;
u64 fs;
u64 gs;
} __packed;
struct desc_struct {
union {
struct {
u32 a;
u32 b;
} x86_32;
u64 base_addr;
};
} __packed;
struct user_fpregs_entry {
u16 cwd;
u16 swd;
u16 twd; /* Note this is not the same as
the 32bit/x87/FSAVE twd */
u16 fop;
u64 rip;
u64 rdp;
u32 mxcsr;
u32 mxcsr_mask;
u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
u32 padding[24];
} __packed;
#define GDT_ENTRY_TLS_ENTRIES 3 #define GDT_ENTRY_TLS_ENTRIES 3
#define TASK_COMM_LEN 16 #define TASK_COMM_LEN 16
#define TASK_PF_USED_MATH 0x00002000 #define TASK_PF_USED_MATH 0x00002000
#define CKPT_ARCH_SIZE (1 * 4096)
struct ckpt_arch_entry {
union {
struct {
struct user_regs_entry gpregs;
struct user_fpregs_entry fpregs;
};
u8 __arch_pad[CKPT_ARCH_SIZE]; /* should be enough for all */
};
};
#define CKPT_CORE_SIZE (2 * 4096)
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
# define AT_VECTOR_SIZE 44 # define AT_VECTOR_SIZE 44
#else #else
# define AT_VECTOR_SIZE 22 /* Not needed at moment */ # define AT_VECTOR_SIZE 22 /* Not needed at moment */
#endif #endif
struct task_core_entry {
u8 task_state;
u8 pad[3];
u32 exit_code;
u32 personality;
u8 comm[TASK_COMM_LEN];
u32 flags;
u64 blk_sigset;
};
struct core_ids_entry {
u32 vm_id;
u32 files_id;
u32 fs_id;
u32 sighand_id;
} __packed;
struct core_entry {
union {
struct {
struct image_header header;
struct task_core_entry tc;
struct ckpt_arch_entry arch;
struct core_ids_entry ids;
u64 clear_tid_address;
};
u8 __core_pad[CKPT_CORE_SIZE];
};
} __packed;
#define TASK_ALIVE 0x1 #define TASK_ALIVE 0x1
#define TASK_DEAD 0x2 #define TASK_DEAD 0x2
#define TASK_STOPPED 0x3 /* FIXME - implement */ #define TASK_STOPPED 0x3 /* FIXME - implement */
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "../protobuf/mm.pb-c.h" #include "../protobuf/mm.pb-c.h"
#include "../protobuf/vma.pb-c.h" #include "../protobuf/vma.pb-c.h"
#include "../protobuf/creds.pb-c.h" #include "../protobuf/creds.pb-c.h"
#include "../protobuf/core.pb-c.h"
#ifndef CONFIG_X86_64 #ifndef CONFIG_X86_64
# error Only x86-64 is supported # error Only x86-64 is supported
...@@ -60,15 +61,15 @@ struct thread_restore_args { ...@@ -60,15 +61,15 @@ struct thread_restore_args {
struct restore_mem_zone mem_zone; struct restore_mem_zone mem_zone;
int pid; int pid;
int fd_core;
mutex_t *rst_lock; mutex_t *rst_lock;
UserX86RegsEntry gpregs;
u64 clear_tid_addr;
} __aligned(sizeof(long)); } __aligned(sizeof(long));
struct task_restore_core_args { struct task_restore_core_args {
struct restore_mem_zone mem_zone; struct restore_mem_zone mem_zone;
int pid; /* task pid */ int pid; /* task pid */
int fd_core; /* opened core file */
int fd_exe_link; /* opened self->exe file */ int fd_exe_link; /* opened self->exe file */
int fd_pages; /* opened pages dump file */ int fd_pages; /* opened pages dump file */
int logfd; int logfd;
...@@ -95,6 +96,11 @@ struct task_restore_core_args { ...@@ -95,6 +96,11 @@ struct task_restore_core_args {
MmEntry mm; MmEntry mm;
u64 mm_saved_auxv[AT_VECTOR_SIZE]; u64 mm_saved_auxv[AT_VECTOR_SIZE];
u64 clear_tid_addr;
u64 blk_sigset;
char comm[TASK_COMM_LEN];
TaskKobjIdsEntry ids;
UserX86RegsEntry gpregs;
} __aligned(sizeof(long)); } __aligned(sizeof(long));
struct pt_regs { struct pt_regs {
......
...@@ -51,6 +51,7 @@ PROTO_FILES += ipc-sem.proto ...@@ -51,6 +51,7 @@ PROTO_FILES += ipc-sem.proto
PROTO_FILES += utsns.proto PROTO_FILES += utsns.proto
PROTO_FILES += creds.proto PROTO_FILES += creds.proto
PROTO_FILES += vma.proto PROTO_FILES += vma.proto
PROTO_FILES += core.proto
HDRS := $(patsubst %.proto,%.pb-c.h,$(PROTO_FILES)) HDRS := $(patsubst %.proto,%.pb-c.h,$(PROTO_FILES))
SRCS := $(patsubst %.proto,%.pb-c.c,$(PROTO_FILES)) SRCS := $(patsubst %.proto,%.pb-c.c,$(PROTO_FILES))
......
message user_x86_regs_entry {
required uint64 r15 = 1;
required uint64 r14 = 2;
required uint64 r13 = 3;
required uint64 r12 = 4;
required uint64 bp = 5;
required uint64 bx = 6;
required uint64 r11 = 7;
required uint64 r10 = 8;
required uint64 r9 = 9;
required uint64 r8 = 10;
required uint64 ax = 11;
required uint64 cx = 12;
required uint64 dx = 13;
required uint64 si = 14;
required uint64 di = 15;
required uint64 orig_ax = 16;
required uint64 ip = 17;
required uint64 cs = 18;
required uint64 flags = 19;
required uint64 sp = 20;
required uint64 ss = 21;
required uint64 fs_base = 22;
required uint64 gs_base = 23;
required uint64 ds = 24;
required uint64 es = 25;
required uint64 fs = 26;
required uint64 gs = 27;
}
message user_x86_fpregs_entry {
required uint32 cwd = 1;
required uint32 swd = 2;
required uint32 twd = 3;
required uint32 fop = 4;
required uint64 rip = 5;
required uint64 rdp = 6;
required uint32 mxcsr = 7;
required uint32 mxcsr_mask = 8;
repeated uint32 st_space = 9;
repeated uint32 xmm_space = 10;
repeated uint32 padding = 11;
}
message task_core_entry {
required uint32 task_state = 1;
required uint32 exit_code = 2;
required uint32 personality = 3;
required uint32 flags = 4;
required uint64 blk_sigset = 5;
required string comm = 6;
}
message task_kobj_ids_entry {
required uint32 vm_id = 1;
required uint32 files_id = 2;
required uint32 fs_id = 3;
required uint32 sighand_id = 4;
}
message thread_info_x86 {
required uint64 clear_tid_addr = 1;
required user_x86_regs_entry gpregs = 2;
required user_x86_fpregs_entry fpregs = 3;
}
message core_entry {
enum march {
UNKNOWN = 0;
X86_64 = 1;
}
required march mtype = 1;
optional thread_info_x86 thread_info = 2;
optional task_core_entry tc = 3;
optional task_kobj_ids_entry ids = 4;
}
...@@ -131,7 +131,6 @@ static void restore_creds(CredsEntry *ce) ...@@ -131,7 +131,6 @@ static void restore_creds(CredsEntry *ce)
long __export_restore_thread(struct thread_restore_args *args) long __export_restore_thread(struct thread_restore_args *args)
{ {
long ret = -1; long ret = -1;
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(); int my_pid = sys_gettid();
...@@ -143,23 +142,12 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -143,23 +142,12 @@ long __export_restore_thread(struct thread_restore_args *args)
goto core_restore_end; goto core_restore_end;
} }
core_entry = (struct core_entry *)&args->mem_zone.heap; sys_set_tid_address((int *)args->clear_tid_addr);
ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
if (ret != sizeof(*core_entry)) {
write_num_n(__LINE__);
goto core_restore_end;
}
/* We're to close it! */
sys_close(args->fd_core);
sys_set_tid_address((int *) core_entry->clear_tid_address);
rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8; rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
#define CPREGT1(d) rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.d #define CPREGT1(d) rt_sigframe->uc.uc_mcontext.d = args->gpregs.d
#define CPREGT2(d,s) rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.s #define CPREGT2(d,s) rt_sigframe->uc.uc_mcontext.d = args->gpregs.s
CPREGT1(r8); CPREGT1(r8);
CPREGT1(r9); CPREGT1(r9);
...@@ -183,7 +171,7 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -183,7 +171,7 @@ long __export_restore_thread(struct thread_restore_args *args)
CPREGT1(gs); CPREGT1(gs);
CPREGT1(fs); CPREGT1(fs);
fsgs_base = core_entry->arch.gpregs.fs_base; fsgs_base = args->gpregs.fs_base;
ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base); ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
if (ret) { if (ret) {
write_num_n(__LINE__); write_num_n(__LINE__);
...@@ -191,7 +179,7 @@ long __export_restore_thread(struct thread_restore_args *args) ...@@ -191,7 +179,7 @@ long __export_restore_thread(struct thread_restore_args *args)
goto core_restore_end; goto core_restore_end;
} }
fsgs_base = core_entry->arch.gpregs.gs_base; fsgs_base = args->gpregs.gs_base;
ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base); ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
if (ret) { if (ret) {
write_num_n(__LINE__); write_num_n(__LINE__);
...@@ -294,7 +282,6 @@ static u64 restore_mapping(const VmaEntry *vma_entry) ...@@ -294,7 +282,6 @@ static u64 restore_mapping(const VmaEntry *vma_entry)
long __export_restore_task(struct task_restore_core_args *args) long __export_restore_task(struct task_restore_core_args *args)
{ {
long ret = -1; long ret = -1;
struct core_entry *core_entry;
VmaEntry *vma_entry; VmaEntry *vma_entry;
u64 va; u64 va;
...@@ -310,8 +297,6 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -310,8 +297,6 @@ long __export_restore_task(struct task_restore_core_args *args)
restorer_set_logfd(args->logfd); restorer_set_logfd(args->logfd);
core_entry = first_on_heap(core_entry, args->mem_zone.heap);
#if 0 #if 0
write_hex_n((long)args); write_hex_n((long)args);
write_hex_n((long)args->mem_zone.heap); write_hex_n((long)args->mem_zone.heap);
...@@ -319,12 +304,6 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -319,12 +304,6 @@ long __export_restore_task(struct task_restore_core_args *args)
write_hex_n((long)vma_entry); write_hex_n((long)vma_entry);
#endif #endif
ret = sys_read(args->fd_core, core_entry, sizeof(*core_entry));
if (ret != sizeof(*core_entry)) {
write_num_n(__LINE__);
goto core_restore_end;
}
for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) { for (vma_entry = args->self_vmas; vma_entry->start != 0; vma_entry++) {
if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR)) if (!vma_entry_is(vma_entry, VMA_AREA_REGULAR))
continue; continue;
...@@ -412,7 +391,6 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -412,7 +391,6 @@ long __export_restore_task(struct task_restore_core_args *args)
sys_munmap(args->tgt_vmas, sys_munmap(args->tgt_vmas,
((void *)(vma_entry + 1) - ((void *)args->tgt_vmas))); ((void *)(vma_entry + 1) - ((void *)args->tgt_vmas)));
sys_close(args->fd_core);
ret = sys_munmap(args->shmems, SHMEMS_SIZE); ret = sys_munmap(args->shmems, SHMEMS_SIZE);
if (ret < 0) { if (ret < 0) {
...@@ -421,12 +399,12 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -421,12 +399,12 @@ long __export_restore_task(struct task_restore_core_args *args)
goto core_restore_end; goto core_restore_end;
} }
sys_set_tid_address((int *) core_entry->clear_tid_address); sys_set_tid_address((int *)args->clear_tid_addr);
/* /*
* Tune up the task fields. * Tune up the task fields.
*/ */
ret |= sys_prctl_safe(PR_SET_NAME, (long)core_entry->tc.comm, 0, 0); ret |= sys_prctl_safe(PR_SET_NAME, (long)args->comm, 0, 0);
ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE, (long)args->mm.mm_start_code, 0); ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_START_CODE, (long)args->mm.mm_start_code, 0);
ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE, (long)args->mm.mm_end_code, 0); ret |= sys_prctl_safe(PR_SET_MM, PR_SET_MM_END_CODE, (long)args->mm.mm_end_code, 0);
...@@ -462,8 +440,8 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -462,8 +440,8 @@ long __export_restore_task(struct task_restore_core_args *args)
*/ */
rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8; rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;
#define CPREG1(d) rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.d #define CPREG1(d) rt_sigframe->uc.uc_mcontext.d = args->gpregs.d
#define CPREG2(d,s) rt_sigframe->uc.uc_mcontext.d = core_entry->arch.gpregs.s #define CPREG2(d,s) rt_sigframe->uc.uc_mcontext.d = args->gpregs.s
CPREG1(r8); CPREG1(r8);
CPREG1(r9); CPREG1(r9);
...@@ -487,7 +465,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -487,7 +465,7 @@ long __export_restore_task(struct task_restore_core_args *args)
CPREG1(gs); CPREG1(gs);
CPREG1(fs); CPREG1(fs);
fsgs_base = core_entry->arch.gpregs.fs_base; fsgs_base = args->gpregs.fs_base;
ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base); ret = sys_arch_prctl(ARCH_SET_FS, fsgs_base);
if (ret) { if (ret) {
write_num_n(__LINE__); write_num_n(__LINE__);
...@@ -495,7 +473,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -495,7 +473,7 @@ long __export_restore_task(struct task_restore_core_args *args)
goto core_restore_end; goto core_restore_end;
} }
fsgs_base = core_entry->arch.gpregs.gs_base; fsgs_base = args->gpregs.gs_base;
ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base); ret = sys_arch_prctl(ARCH_SET_GS, fsgs_base);
if (ret) { if (ret) {
write_num_n(__LINE__); write_num_n(__LINE__);
...@@ -506,7 +484,7 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -506,7 +484,7 @@ long __export_restore_task(struct task_restore_core_args *args)
/* /*
* Blocked signals. * Blocked signals.
*/ */
rt_sigframe->uc.uc_sigmask.sig[0] = core_entry->tc.blk_sigset; rt_sigframe->uc.uc_sigmask.sig[0] = args->blk_sigset;
/* /*
* Threads restoration. This requires some more comments. This * Threads restoration. This requires some more comments. This
......
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