Commit 4389c021 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

dump, kernel: Add some mm structure members into the dump

Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent ce65f2f7
...@@ -417,12 +417,19 @@ err: ...@@ -417,12 +417,19 @@ err:
#define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e)) #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, 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; FILE *file = NULL;
char *tok1, *tok2; char *tok1, *tok2;
int i, ret = -1; 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); snprintf(loc_buf, sizeof(loc_buf), "/proc/%d/stat", pid);
file = fopen(loc_buf, "r"); file = fopen(loc_buf, "r");
if (!file) { if (!file) {
...@@ -448,7 +455,7 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags, ...@@ -448,7 +455,7 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags,
if (!ret) { if (!ret) {
ret = -1; ret = -1;
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
tok1 = strtok(NULL, " "); tok1 = strtok(NULL, " \n\t");
if (!tok1) if (!tok1)
goto err_corrupted; goto err_corrupted;
} }
...@@ -458,22 +465,53 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags, ...@@ -458,22 +465,53 @@ static int get_task_stat(pid_t pid, u8 *comm, u32 *flags,
if (!ret) { if (!ret) {
ret = -1; ret = -1;
for (i = 0; i < 15; i++) { for (i = 0; i < 16; i++) {
tok1 = strtok(NULL, " "); tok1 = strtok(NULL, " \n\t");
if (!tok1) if (!tok1)
goto err_corrupted; goto err_corrupted;
} }
tok1 = strtok(NULL, " "); tok1 = strtok(NULL, " \n\t");
if (!tok1) if (!tok1)
goto err_corrupted; goto err_corrupted;
*start_code = atol(tok1); *start_code = atol(tok1);
tok1 = strtok(NULL, " "); tok1 = strtok(NULL, " \n\t");
if (!tok1) if (!tok1)
goto err_corrupted; goto err_corrupted;
*end_code = atol(tok1); *end_code = atol(tok1);
ret = 0; 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: err:
...@@ -645,7 +683,11 @@ static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset) ...@@ -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, ret = get_task_stat(pid, core->task_comm,
&core->task_flags, &core->task_flags,
&core->mm_start_code, &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) if (ret)
goto err_free; goto err_free;
pr_info("OK\n"); pr_info("OK\n");
......
...@@ -108,6 +108,7 @@ static void show_core_rest(struct cr_fdset *cr_fdset) ...@@ -108,6 +108,7 @@ static void show_core_rest(struct cr_fdset *cr_fdset)
u32 personality; u32 personality;
char comm[TASK_COMM_LEN]; char comm[TASK_COMM_LEN];
u64 mm_brk, mm_start_code, mm_end_code; 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; fd_core = cr_fdset->desc[CR_FD_CORE].fd;
if (fd_core < 0) if (fd_core < 0)
...@@ -128,11 +129,28 @@ static void show_core_rest(struct cr_fdset *cr_fdset) ...@@ -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); lseek(fd_core, GET_FILE_OFF(struct core_entry, mm_end_code), SEEK_SET);
read_ptr_safe(fd_core, &mm_end_code, err); read_ptr_safe(fd_core, &mm_end_code, err);
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("Personality: %x\n", personality);
pr_info("Command: %s\n", comm); pr_info("Command: %s\n", comm);
pr_info("Brk: %lx\n", mm_brk); pr_info("Brk: %lx\n", mm_brk);
pr_info("Start code: %lx\n", mm_start_code); pr_info("Start code: %lx\n", mm_start_code);
pr_info("End code: %lx\n", mm_end_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: err:
return; return;
} }
......
...@@ -167,8 +167,8 @@ struct ckpt_arch_entry { ...@@ -167,8 +167,8 @@ struct ckpt_arch_entry {
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
}; };
#define CKPT_ARCH_SIZE 2048 #define CKPT_ARCH_SIZE (2 * 4096)
#define CKPT_CORE_SIZE 8192 #define CKPT_CORE_SIZE (4 * 4096)
struct core_entry { struct core_entry {
union { union {
...@@ -181,9 +181,13 @@ struct core_entry { ...@@ -181,9 +181,13 @@ struct core_entry {
u32 task_personality; u32 task_personality;
u8 task_comm[TASK_COMM_LEN]; u8 task_comm[TASK_COMM_LEN];
u32 task_flags; u32 task_flags;
u64 mm_brk;
u64 mm_start_code; u64 mm_start_code;
u64 mm_end_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]; u8 __core_pad[CKPT_CORE_SIZE];
}; };
......
...@@ -25,18 +25,19 @@ v2: (from Andrew Vagin) ...@@ -25,18 +25,19 @@ v2: (from Andrew Vagin)
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
--- ---
arch/x86/include/asm/elf.h | 3 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/Makefile | 2
arch/x86/kernel/elf_ckpt.c | 161 ++++++++++++++++ arch/x86/kernel/elf_ckpt.c | 161 +++++++++++++++++++
arch/x86/vdso/vma.c | 22 ++ arch/x86/vdso/vma.c | 22 ++
fs/Kconfig.binfmt | 11 + fs/Kconfig.binfmt | 11 +
fs/Makefile | 1 fs/Makefile | 1
fs/binfmt_elf.c | 17 + fs/binfmt_elf.c | 17 +-
fs/binfmt_elf_ckpt.c | 389 ++++++++++++++++++++++++++++++++++++++++ fs/binfmt_elf_ckpt.c | 332 ++++++++++++++++++++++++++++++++++++++++
fs/exec.c | 27 +- fs/exec.c | 27 ++-
fs/proc/array.c | 7
include/linux/binfmts.h | 1 include/linux/binfmts.h | 1
include/linux/elf_ckpt.h | 99 ++++++++++ include/linux/elf_ckpt.h | 103 ++++++++++++
12 files changed, 801 insertions(+), 12 deletions(-) 13 files changed, 753 insertions(+), 14 deletions(-)
Index: linux-2.6.git/arch/x86/include/asm/elf.h 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 ...@@ -429,7 +430,7 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ linux-2.6.git/fs/binfmt_elf_ckpt.c +++ linux-2.6.git/fs/binfmt_elf_ckpt.c
@@ -0,0 +1,389 @@ @@ -0,0 +1,332 @@
+#include <linux/module.h> +#include <linux/module.h>
+#include <linux/kernel.h> +#include <linux/kernel.h>
+#include <linux/fs.h> +#include <linux/fs.h>
...@@ -481,9 +482,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c ...@@ -481,9 +482,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
+ struct file *file = NULL; + struct file *file = NULL;
+ unsigned long map_addr; + 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 +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
+ unsigned long vdso = -1UL; + unsigned long vdso = -1UL;
+#endif +#endif
...@@ -501,15 +499,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c ...@@ -501,15 +499,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
+ nr_vma_found = 0; + nr_vma_found = 0;
+ nr_vma_mapped = 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); + 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)) { + if (!fa || flex_array_prealloc(fa, 0, elf_ex->e_phnum, GFP_KERNEL)) {
+ ret = -ENOMEM; + ret = -ENOMEM;
...@@ -616,14 +605,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c ...@@ -616,14 +605,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
+ for (i = 0; i < nr_vma_found; i++) { + for (i = 0; i < nr_vma_found; i++) {
+ vma_entry_ptr = flex_array_get(fa, 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 +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
+ if (vma_entry_ptr->status & VMA_AREA_VDSO) + if (vma_entry_ptr->status & VMA_AREA_VDSO)
+ vdso = vma_entry_ptr->start; + vdso = vma_entry_ptr->start;
...@@ -665,37 +646,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c ...@@ -665,37 +646,6 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
+ goto out_unmap; + 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++; + nr_vma_mapped++;
+ } + }
+ +
...@@ -711,20 +661,14 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c ...@@ -711,20 +661,14 @@ Index: linux-2.6.git/fs/binfmt_elf_ckpt.c
+ /* The name it has before */ + /* The name it has before */
+ set_task_comm(current, core_entry->task_comm); + set_task_comm(current, core_entry->task_comm);
+ +
+ bprm->p = start_stack; + bprm->p = core_entry->mm_start_stack;
+
+ if (start_brk == -1UL) {
+ pr_err("elf-ckpt: Can't find brk area\n");
+ ret = -ENOEXEC;
+ goto out_unmap;
+ }
+ +
+ current->mm->start_code = core_entry->mm_start_code; + current->mm->start_code = core_entry->mm_start_code;
+ current->mm->end_code = core_entry->mm_end_code; + current->mm->end_code = core_entry->mm_end_code;
+ current->mm->start_data = start_data; + current->mm->start_data = core_entry->mm_start_data;
+ current->mm->end_data = end_data; + current->mm->end_data = core_entry->mm_end_data;
+ current->mm->start_stack = start_stack; + current->mm->start_stack = core_entry->mm_start_stack;
+ current->mm->start_brk = start_brk; + current->mm->start_brk = core_entry->mm_start_brk;
+ current->mm->brk = core_entry->mm_brk; + current->mm->brk = core_entry->mm_brk;
+ +
+#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
...@@ -870,6 +814,31 @@ Index: linux-2.6.git/fs/exec.c ...@@ -870,6 +814,31 @@ Index: linux-2.6.git/fs/exec.c
EXPORT_SYMBOL(flush_old_exec); EXPORT_SYMBOL(flush_old_exec);
void would_dump(struct linux_binprm *bprm, struct file *file) 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 Index: linux-2.6.git/include/linux/binfmts.h
=================================================================== ===================================================================
--- linux-2.6.git.orig/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 ...@@ -886,7 +855,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ linux-2.6.git/include/linux/elf_ckpt.h +++ linux-2.6.git/include/linux/elf_ckpt.h
@@ -0,0 +1,99 @@ @@ -0,0 +1,103 @@
+#ifndef _LINUX_ELF_CHECKPOINT_H +#ifndef _LINUX_ELF_CHECKPOINT_H
+#define _LINUX_ELF_CHECKPOINT_H +#define _LINUX_ELF_CHECKPOINT_H
+ +
...@@ -953,8 +922,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -953,8 +922,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+ __u32 flags; + __u32 flags;
+} __packed; +} __packed;
+ +
+#define CKPT_ARCH_SIZE 2048 +#define CKPT_ARCH_SIZE (2 * 4096)
+#define CKPT_CORE_SIZE 8192 +#define CKPT_CORE_SIZE (4 * 4096)
+ +
+struct core_entry { +struct core_entry {
+ union { + union {
...@@ -964,9 +933,13 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -964,9 +933,13 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+ __u32 task_personality; + __u32 task_personality;
+ __u8 task_comm[CKPT_TASK_COMM_LEN]; + __u8 task_comm[CKPT_TASK_COMM_LEN];
+ __u32 task_flags; + __u32 task_flags;
+ __u64 mm_brk;
+ __u64 mm_start_code; + __u64 mm_start_code;
+ __u64 mm_end_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]; + __u8 __core_pad[CKPT_CORE_SIZE];
+ }; + };
......
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