mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 18:07:57 +00:00
dump, kernel: Add some mm structure members into the dump
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
parent
ce65f2f718
commit
4389c021fc
56
cr-dump.c
56
cr-dump.c
@ -417,12 +417,19 @@ err:
|
||||
#define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e))
|
||||
|
||||
static int get_task_stat(pid_t pid, u8 *comm, u32 *flags,
|
||||
u64 *start_code, u64 *end_code)
|
||||
u64 *start_code, u64 *end_code,
|
||||
u64 *start_data, u64 *end_data,
|
||||
u64 *start_stack, u64 *start_brk)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
char *tok1, *tok2;
|
||||
int i, ret = -1;
|
||||
|
||||
/*
|
||||
* NOTE: Be careful, /proc/$pid/stat has a parasite
|
||||
* '0' symbol at argument 20 in format string.
|
||||
*/
|
||||
|
||||
snprintf(loc_buf, sizeof(loc_buf), "/proc/%d/stat", pid);
|
||||
file = fopen(loc_buf, "r");
|
||||
if (!file) {
|
||||
@ -448,7 +455,7 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags,
|
||||
if (!ret) {
|
||||
ret = -1;
|
||||
for (i = 0; i < 7; i++) {
|
||||
tok1 = strtok(NULL, " ");
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
}
|
||||
@ -458,22 +465,53 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags,
|
||||
|
||||
if (!ret) {
|
||||
ret = -1;
|
||||
for (i = 0; i < 15; i++) {
|
||||
tok1 = strtok(NULL, " ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
}
|
||||
|
||||
tok1 = strtok(NULL, " ");
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*start_code = atol(tok1);
|
||||
|
||||
tok1 = strtok(NULL, " ");
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*end_code = atol(tok1);
|
||||
ret = 0;
|
||||
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*start_stack = atol(tok1);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
ret = -1;
|
||||
for (i = 0; i < 16; i++) {
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
}
|
||||
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*start_data = atol(tok1);
|
||||
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*end_data = atol(tok1);
|
||||
|
||||
tok1 = strtok(NULL, " \n\t");
|
||||
if (!tok1)
|
||||
goto err_corrupted;
|
||||
*start_brk = atol(tok1);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
err:
|
||||
@ -645,7 +683,11 @@ static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset)
|
||||
ret = get_task_stat(pid, core->task_comm,
|
||||
&core->task_flags,
|
||||
&core->mm_start_code,
|
||||
&core->mm_end_code);
|
||||
&core->mm_end_code,
|
||||
&core->mm_start_data,
|
||||
&core->mm_end_data,
|
||||
&core->mm_start_stack,
|
||||
&core->mm_start_brk);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
pr_info("OK\n");
|
||||
|
28
cr-show.c
28
cr-show.c
@ -108,6 +108,7 @@ static void show_core_rest(struct cr_fdset *cr_fdset)
|
||||
u32 personality;
|
||||
char comm[TASK_COMM_LEN];
|
||||
u64 mm_brk, mm_start_code, mm_end_code;
|
||||
u64 mm_start_data, mm_end_data, mm_start_stack, mm_start_brk;
|
||||
|
||||
fd_core = cr_fdset->desc[CR_FD_CORE].fd;
|
||||
if (fd_core < 0)
|
||||
@ -128,11 +129,28 @@ static void show_core_rest(struct cr_fdset *cr_fdset)
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_end_code), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_end_code, err);
|
||||
|
||||
pr_info("Personality: %x\n", personality);
|
||||
pr_info("Command: %s\n", comm);
|
||||
pr_info("Brk: %lx\n", mm_brk);
|
||||
pr_info("Start code: %lx\n", mm_start_code);
|
||||
pr_info("End code: %lx\n", mm_end_code);
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_start_stack), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_stack, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_start_data), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_data, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_end_data), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_end_data, err);
|
||||
|
||||
lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_start_brk), SEEK_SET);
|
||||
read_ptr_safe(fd_core, &mm_start_brk, err);
|
||||
|
||||
pr_info("Personality: %x\n", personality);
|
||||
pr_info("Command: %s\n", comm);
|
||||
pr_info("Brk: %lx\n", mm_brk);
|
||||
pr_info("Start code: %lx\n", mm_start_code);
|
||||
pr_info("End code: %lx\n", mm_end_code);
|
||||
pr_info("Start stack: %lx\n", mm_end_code);
|
||||
pr_info("Start data: %lx\n", mm_end_code);
|
||||
pr_info("End data: %lx\n", mm_end_code);
|
||||
pr_info("Start brk: %lx\n", mm_end_code);
|
||||
|
||||
err:
|
||||
return;
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ struct ckpt_arch_entry {
|
||||
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
|
||||
};
|
||||
|
||||
#define CKPT_ARCH_SIZE 2048
|
||||
#define CKPT_CORE_SIZE 8192
|
||||
#define CKPT_ARCH_SIZE (2 * 4096)
|
||||
#define CKPT_CORE_SIZE (4 * 4096)
|
||||
|
||||
struct core_entry {
|
||||
union {
|
||||
@ -181,9 +181,13 @@ struct core_entry {
|
||||
u32 task_personality;
|
||||
u8 task_comm[TASK_COMM_LEN];
|
||||
u32 task_flags;
|
||||
u64 mm_brk;
|
||||
u64 mm_start_code;
|
||||
u64 mm_end_code;
|
||||
u64 mm_start_data;
|
||||
u64 mm_end_data;
|
||||
u64 mm_start_stack;
|
||||
u64 mm_start_brk;
|
||||
u64 mm_brk;
|
||||
};
|
||||
u8 __core_pad[CKPT_CORE_SIZE];
|
||||
};
|
||||
|
@ -25,18 +25,19 @@ v2: (from Andrew Vagin)
|
||||
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
|
||||
---
|
||||
arch/x86/include/asm/elf.h | 3
|
||||
arch/x86/include/asm/elf_ckpt.h | 80 ++++++++
|
||||
arch/x86/include/asm/elf_ckpt.h | 80 +++++++++
|
||||
arch/x86/kernel/Makefile | 2
|
||||
arch/x86/kernel/elf_ckpt.c | 161 ++++++++++++++++
|
||||
arch/x86/kernel/elf_ckpt.c | 161 +++++++++++++++++++
|
||||
arch/x86/vdso/vma.c | 22 ++
|
||||
fs/Kconfig.binfmt | 11 +
|
||||
fs/Makefile | 1
|
||||
fs/binfmt_elf.c | 17 +
|
||||
fs/binfmt_elf_ckpt.c | 389 ++++++++++++++++++++++++++++++++++++++++
|
||||
fs/exec.c | 27 +-
|
||||
fs/binfmt_elf.c | 17 +-
|
||||
fs/binfmt_elf_ckpt.c | 332 ++++++++++++++++++++++++++++++++++++++++
|
||||
fs/exec.c | 27 ++-
|
||||
fs/proc/array.c | 7
|
||||
include/linux/binfmts.h | 1
|
||||
include/linux/elf_ckpt.h | 99 ++++++++++
|
||||
12 files changed, 801 insertions(+), 12 deletions(-)
|
||||
include/linux/elf_ckpt.h | 103 ++++++++++++
|
||||
13 files changed, 753 insertions(+), 14 deletions(-)
|
||||
|
||||
Index: linux-2.6.git/arch/x86/include/asm/elf.h
|
||||
===================================================================
|
||||
@ -429,7 +430,7 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
@@ -0,0 +1,389 @@
|
||||
@@ -0,0 +1,332 @@
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/fs.h>
|
||||
@ -481,9 +482,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
+ struct file *file = NULL;
|
||||
+ unsigned long map_addr;
|
||||
+
|
||||
+ unsigned long start_code, end_code, start_data, end_data;
|
||||
+ unsigned long start_brk, start_stack;
|
||||
+
|
||||
+#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
+ unsigned long vdso = -1UL;
|
||||
+#endif
|
||||
@ -501,15 +499,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
+ nr_vma_found = 0;
|
||||
+ nr_vma_mapped = 0;
|
||||
+
|
||||
+ start_code = -1UL;
|
||||
+ end_code = 0;
|
||||
+
|
||||
+ start_data = -1UL;
|
||||
+ end_data = 0;
|
||||
+
|
||||
+ start_stack = -1UL;
|
||||
+ start_brk = -1UL;
|
||||
+
|
||||
+ fa = flex_array_alloc(sizeof(vma_entry), elf_ex->e_phnum, GFP_KERNEL);
|
||||
+ if (!fa || flex_array_prealloc(fa, 0, elf_ex->e_phnum, GFP_KERNEL)) {
|
||||
+ ret = -ENOMEM;
|
||||
@ -616,14 +605,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
+ for (i = 0; i < nr_vma_found; i++) {
|
||||
+ vma_entry_ptr = flex_array_get(fa, i);
|
||||
+
|
||||
+ /*
|
||||
+ * This [heap] area is not explicitly existing on old kernels
|
||||
+ * so if it's not found we need to setup brk area from saved
|
||||
+ * brk value.
|
||||
+ */
|
||||
+ if (vma_entry_ptr->status & VMA_AREA_HEAP)
|
||||
+ start_brk = vma_entry_ptr->start;
|
||||
+
|
||||
+#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
+ if (vma_entry_ptr->status & VMA_AREA_VDSO)
|
||||
+ vdso = vma_entry_ptr->start;
|
||||
@ -665,37 +646,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
+ goto out_unmap;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Some heuristics to guess previously loaded real
|
||||
+ * elf file structure. Probably this things should
|
||||
+ * be exported via /proc somewhere instead.
|
||||
+ */
|
||||
+
|
||||
+ if (vma_entry_ptr->status & VMA_AREA_STACK) {
|
||||
+ /* Note if stack is VM_GROWSUP -- it should be reversed */
|
||||
+ start_stack = vma_entry_ptr->start;
|
||||
+ }
|
||||
+
|
||||
+ if (vma_entry_ptr->prot & PROT_EXEC) {
|
||||
+ if (start_code > vma_entry_ptr->start)
|
||||
+ start_code = vma_entry_ptr->start;
|
||||
+ if (end_code < vma_entry_ptr->end)
|
||||
+ end_code = vma_entry_ptr->end;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Neither .bss nor .data was being file mapped.
|
||||
+ * FIXME: .rodata are loaded by interp.
|
||||
+ */
|
||||
+ if (!file) {
|
||||
+ if (vma_entry_ptr->prot & (PROT_WRITE)) {
|
||||
+ if (start_data > vma_entry_ptr->start)
|
||||
+ start_data = vma_entry_ptr->start;
|
||||
+ if (end_data < vma_entry_ptr->end)
|
||||
+ end_data = vma_entry_ptr->end;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ nr_vma_mapped++;
|
||||
+ }
|
||||
+
|
||||
@ -711,20 +661,14 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
|
||||
+ /* The name it has before */
|
||||
+ set_task_comm(current, core_entry->task_comm);
|
||||
+
|
||||
+ bprm->p = start_stack;
|
||||
+
|
||||
+ if (start_brk == -1UL) {
|
||||
+ pr_err("elf-ckpt: Can't find brk area\n");
|
||||
+ ret = -ENOEXEC;
|
||||
+ goto out_unmap;
|
||||
+ }
|
||||
+ bprm->p = core_entry->mm_start_stack;
|
||||
+
|
||||
+ current->mm->start_code = core_entry->mm_start_code;
|
||||
+ current->mm->end_code = core_entry->mm_end_code;
|
||||
+ current->mm->start_data = start_data;
|
||||
+ current->mm->end_data = end_data;
|
||||
+ current->mm->start_stack = start_stack;
|
||||
+ current->mm->start_brk = start_brk;
|
||||
+ current->mm->start_data = core_entry->mm_start_data;
|
||||
+ current->mm->end_data = core_entry->mm_end_data;
|
||||
+ current->mm->start_stack = core_entry->mm_start_stack;
|
||||
+ current->mm->start_brk = core_entry->mm_start_brk;
|
||||
+ current->mm->brk = core_entry->mm_brk;
|
||||
+
|
||||
+#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
@ -870,6 +814,31 @@ Index: linux-2.6.git/fs/exec.c
|
||||
EXPORT_SYMBOL(flush_old_exec);
|
||||
|
||||
void would_dump(struct linux_binprm *bprm, struct file *file)
|
||||
Index: linux-2.6.git/fs/proc/array.c
|
||||
===================================================================
|
||||
--- linux-2.6.git.orig/fs/proc/array.c
|
||||
+++ linux-2.6.git/fs/proc/array.c
|
||||
@@ -478,7 +478,7 @@ static int do_task_stat(struct seq_file
|
||||
|
||||
seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
|
||||
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
|
||||
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
|
||||
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n",
|
||||
pid_nr_ns(pid, ns),
|
||||
tcomm,
|
||||
state,
|
||||
@@ -525,7 +525,10 @@ static int do_task_stat(struct seq_file
|
||||
task->policy,
|
||||
(unsigned long long)delayacct_blkio_ticks(task),
|
||||
cputime_to_clock_t(gtime),
|
||||
- cputime_to_clock_t(cgtime));
|
||||
+ cputime_to_clock_t(cgtime),
|
||||
+ mm ? (permitted ? mm->start_data : 1) : 0,
|
||||
+ mm ? (permitted ? mm->end_data : 1) : 0,
|
||||
+ mm ? (permitted ? mm->start_brk : 1) : 0);
|
||||
if (mm)
|
||||
mmput(mm);
|
||||
return 0;
|
||||
Index: linux-2.6.git/include/linux/binfmts.h
|
||||
===================================================================
|
||||
--- linux-2.6.git.orig/include/linux/binfmts.h
|
||||
@ -886,7 +855,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ linux-2.6.git/include/linux/elf_ckpt.h
|
||||
@@ -0,0 +1,99 @@
|
||||
@@ -0,0 +1,103 @@
|
||||
+#ifndef _LINUX_ELF_CHECKPOINT_H
|
||||
+#define _LINUX_ELF_CHECKPOINT_H
|
||||
+
|
||||
@ -953,8 +922,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
|
||||
+ __u32 flags;
|
||||
+} __packed;
|
||||
+
|
||||
+#define CKPT_ARCH_SIZE 2048
|
||||
+#define CKPT_CORE_SIZE 8192
|
||||
+#define CKPT_ARCH_SIZE (2 * 4096)
|
||||
+#define CKPT_CORE_SIZE (4 * 4096)
|
||||
+
|
||||
+struct core_entry {
|
||||
+ union {
|
||||
@ -964,9 +933,13 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
|
||||
+ __u32 task_personality;
|
||||
+ __u8 task_comm[CKPT_TASK_COMM_LEN];
|
||||
+ __u32 task_flags;
|
||||
+ __u64 mm_brk;
|
||||
+ __u64 mm_start_code;
|
||||
+ __u64 mm_end_code;
|
||||
+ __u64 mm_start_data;
|
||||
+ __u64 mm_end_data;
|
||||
+ __u64 mm_start_stack;
|
||||
+ __u64 mm_start_brk;
|
||||
+ __u64 mm_brk;
|
||||
+ };
|
||||
+ __u8 __core_pad[CKPT_CORE_SIZE];
|
||||
+ };
|
||||
|
Loading…
x
Reference in New Issue
Block a user