Description of Problem:
This is a REGRESSION issue.
At fedora makedumpfile has been updated toward v1.5.4. Unfortunately,
this version fails calculating phys_base on sadump format and then
fails converting vmcore.
x86_64 kernel is relocatable kernel and there can be a gap between
the physical address statically assigned to kernel data and texts
and the address that is really assigned to each object corresponding
to the kernel symbols. The gap is phys_base. makedump calculates the
phys_base in an ad-hoc way that comparing the addresses of some of
occurrences of "Linux kernel" strings in certain range of vmcore.
Resolution:
Fix patch has already been posted in upstream. so just back port.
The commit ID are:
commit e23dc0a1aa5fa7a4429f72ff1c2fe87a87291065
commit 92563d7a7a5175ef78c4a94ee269b1b455331b4c
Signed-off-by: arthur <zzou(a)redhat.com>
---
...ache-Allocate-buffers-at-initialization-t.patch | 107 ++++++++++++++++++
...umpfile-cache-Reuse-entry-in-pending-list.patch | 122 +++++++++++++++++++++
kexec-tools.spec | 4 +
3 files changed, 233 insertions(+)
create mode 100644 kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch
create mode 100644 kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch
diff --git a/kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch b/kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch
new file mode 100644
index 0000000..f0889a6
--- /dev/null
+++ b/kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch
@@ -0,0 +1,107 @@
+From 92563d7a7a5175ef78c4a94ee269b1b455331b4c Mon Sep 17 00:00:00 2001
+Message-Id: <92563d7a7a5175ef78c4a94ee269b1b455331b4c.1381891355.git.zzou(a)redhat.com>
+From: HATAYAMA Daisuke <d.hatayama(a)jp.fujitsu.com>
+Date: Tue, 17 Sep 2013 15:29:33 +0900
+Subject: [PATCH] [PATCH 1/2] cache: Allocate buffers at initialization to
+ detect malloc() failure.
+
+malloc() is used in cache_alloc() but there's no check for it. If I
+added check in cache_alloc() directly, cache_alloc() needs to return
+one more error status and code gets somewhat complicated. Instead, I
+move malloc() in initial() to detect allocation failure at
+initialization. By this change, 8 buffers are allocated at the same
+time, no longer incrementally. However, 8 buffers are almost always
+used throughout execution. There's essential differnece from the
+incremental one.
+
+Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)jp.fujitsu.com>
+Signed-off-by: arthur <zzou(a)redhat.com>
+---
+ cache.c | 29 ++++++++++++++++++++++-------
+ cache.h | 1 +
+ makedumpfile.c | 3 +++
+ 3 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/makedumpfile-1.5.4/cache.c b/makedumpfile-1.5.4/cache.c
+index 3bea089..dad8d80 100644
+--- a/makedumpfile-1.5.4/cache.c
++++ b/makedumpfile-1.5.4/cache.c
+@@ -18,6 +18,7 @@
+
+ #include "makedumpfile.h"
+ #include "cache.h"
++#include "print_info.h"
+
+ struct cache_entry {
+ unsigned long long paddr;
+@@ -36,6 +37,25 @@ static int avail = CACHE_SIZE;
+
+ static struct cache used, pending;
+
++int
++cache_init(void)
++{
++ void *bufptr;
++ int i;
++
++ for (i = 0; i < CACHE_SIZE; ++i) {
++ bufptr = malloc(info->page_size);
++ if (bufptr == NULL) {
++ ERRMSG("Can't allocate memory for cache. %s\n",
++ strerror(errno));
++ return FALSE;
++ }
++ pool[i].bufptr = bufptr;
++ }
++
++ return TRUE;
++}
++
+ static void
+ add_entry(struct cache *cache, struct cache_entry *entry)
+ {
+@@ -83,13 +103,8 @@ cache_alloc(unsigned long long paddr)
+ {
+ struct cache_entry *entry = NULL;
+
+- if (avail) {
+- void *bufptr = malloc(info->page_size);
+- if (bufptr) {
+- entry = &pool[--avail];
+- entry->bufptr = bufptr;
+- }
+- }
++ if (avail)
++ entry = &pool[--avail];
+
+ if (!entry) {
+ if (used.tail) {
+diff --git a/makedumpfile-1.5.4/cache.h b/makedumpfile-1.5.4/cache.h
+index f37d883..4730e12 100644
+--- a/makedumpfile-1.5.4/cache.h
++++ b/makedumpfile-1.5.4/cache.h
+@@ -19,6 +19,7 @@
+ #ifndef _CACHE_H
+ #define _CACHE_H
+
++int cache_init(void);
+ void *cache_search(unsigned long long paddr);
+ void *cache_alloc(unsigned long long paddr);
+ void cache_add(unsigned long long paddr);
+diff --git a/makedumpfile-1.5.4/makedumpfile.c b/makedumpfile-1.5.4/makedumpfile.c
+index 1718f88..e01ff50 100644
+--- a/makedumpfile-1.5.4/makedumpfile.c
++++ b/makedumpfile-1.5.4/makedumpfile.c
+@@ -3017,6 +3017,9 @@ out:
+ DEBUG_MSG("Buffer size for the cyclic mode: %ld\n", info->bufsize_cyclic);
+ }
+
++ if (!cache_init())
++ return FALSE;
++
+ if (debug_info) {
+ if (info->flag_sadump)
+ (void) sadump_virt_phys_base();
+--
+1.8.3.1
+
diff --git a/kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch b/kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch
new file mode 100644
index 0000000..bc58c94
--- /dev/null
+++ b/kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch
@@ -0,0 +1,122 @@
+From e23dc0a1aa5fa7a4429f72ff1c2fe87a87291065 Mon Sep 17 00:00:00 2001
+Message-Id: <e23dc0a1aa5fa7a4429f72ff1c2fe87a87291065.1381891368.git.zzou(a)redhat.com>
+From: HATAYAMA Daisuke <d.hatayama(a)jp.fujitsu.com>
+Date: Tue, 17 Sep 2013 15:29:38 +0900
+Subject: [PATCH] [PATCH 2/2] cache: Reuse entry in pending list.
+
+Currently, sadump_virt_phys_base() fails to calculate phys_base as
+below:
+
+$ /pub/repos/makedumpfile/makedumpfile -f -p -d 31 -x /pub3/vmcores/comparevmcore_data/vmlinux-2.6.18-363.el5 /pub3/vmcores/comparevmcore_data/vmcore-2.6.18-363.el5-sadump /pub3/vmcores/comparevmcore_data/vmcore-pd31
+Switched running mode from cyclic to non-cyclic,
+because the cyclic mode doesn't support sadump format.
+readmem: type_addr: 1, addr:296020, size:13
+readmem: type_addr: 1, addr:ffffffffff296020, size:13
+readmem: type_addr: 1, addr:ffffffffff396020, size:13
+readmem: type_addr: 1, addr:ffffffffff496020, size:13
+readmem: type_addr: 1, addr:ffffffffff596020, size:13
+readmem: type_addr: 1, addr:ffffffffff696020, size:13
+readmem: type_addr: 1, addr:ffffffffff796020, size:13
+readmem: type_addr: 1, addr:ffffffffff896020, size:13
+readmem: type_addr: 1, addr:ffffffffff996020, size:13
+readmem: type_addr: 1, addr:ffffffffffa96020, size:13
+readmem: type_addr: 1, addr:ffffffffffb96020, size:13
+readmem: type_addr: 1, addr:ffffffffffc96020, size:13
+readmem: type_addr: 1, addr:ffffffffffd96020, size:13
+readmem: type_addr: 1, addr:ffffffffffe96020, size:13
+readmem: type_addr: 1, addr:fffffffffff96020, size:13
+readmem: type_addr: 1, addr:96020, size:13
+readmem: type_addr: 1, addr:196020, size:13
+readmem: type_addr: 1, addr:296020, size:13
+readmem: type_addr: 1, addr:396020, size:13
+readmem: type_addr: 1, addr:496020, size:13
+readmem: type_addr: 1, addr:596020, size:13
+readmem: type_addr: 1, addr:696020, size:13
+readmem: type_addr: 1, addr:796020, size:13
+readmem: type_addr: 1, addr:896020, size:13
+readmem: type_addr: 1, addr:996020, size:13
+readmem: type_addr: 1, addr:a96020, size:13
+readmem: type_addr: 1, addr:b96020, size:13
+readmem: type_addr: 1, addr:c96020, size:13
+readmem: type_addr: 1, addr:d96020, size:13
+readmem: type_addr: 1, addr:e96020, size:13
+readmem: type_addr: 1, addr:f96020, size:13
+readmem: type_addr: 1, addr:1096020, size:13
+readmem: type_addr: 1, addr:1196020, size:13
+readmem: type_addr: 1, addr:1296020, size:13
+readmem: type_addr: 0, addr:ffffffff8045e260, size:32
+cpu_online_mask_init: Can't read cpu_online_mask memory.
+
+makedumpfile Failed.
+
+By git bisect, I found this bug is caused by the following commit:
+
+commit 0aff0e5174d0708bf1bfb039ab863e1fea8a1029
+Author: Petr Tesarik <ptesarik(a)suse.cz>
+Date: Wed Oct 31 16:12:47 2012 +0900
+
+ [PATCH] keep dumpfile pages in a cache.
+
+Then, I found this bug happens in the following senario.
+
+If one of the readpage_xxx() methods fails reading 8 pages in a row, 8
+entries in pool are fully contained in pending list. Then,
+cache_alloc() returns NULL and this continues forever in the
+execution. In other words, there's assumption in cache_alloc() that if
+pool is fully used, they are fully in used list, not in pending list
+at all. However, the buggy path here breaks the assumption. This patch
+changes cache_alloc() so that it first tries to reuse enty in pending
+list if exists.
+
+In fact, I found this bug in ad-hoc phys_base calculation performed in
+sadump_virt_phys_base(). However, I fixed cache side since this bug
+can occur in general on every vmcore format. Crash dump can contain
+broken data in any part of vmcore and so requested physical address to
+read can be broken likewise.
+
+Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)jp.fujitsu.com>
+Signed-off-by: arthur <zzou(a)redhat.com>
+---
+ cache.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/makedumpfile-1.5.4/cache.c b/makedumpfile-1.5.4/cache.c
+index dad8d80..0dd957c 100644
+--- a/makedumpfile-1.5.4/cache.c
++++ b/makedumpfile-1.5.4/cache.c
+@@ -103,19 +103,20 @@ cache_alloc(unsigned long long paddr)
+ {
+ struct cache_entry *entry = NULL;
+
+- if (avail)
++ if (avail) {
+ entry = &pool[--avail];
+-
+- if (!entry) {
+- if (used.tail) {
+- entry = used.tail;
+- remove_entry(&used, entry);
+- } else
+- return NULL;
+- }
+-
+- entry->paddr = paddr;
+- add_entry(&pending, entry);
++ entry->paddr = paddr;
++ add_entry(&pending, entry);
++ } else if (pending.tail) {
++ entry = pending.tail;
++ entry->paddr = paddr;
++ } else if (used.tail) {
++ entry = used.tail;
++ remove_entry(&used, entry);
++ entry->paddr = paddr;
++ add_entry(&pending, entry);
++ } else
++ return NULL;
+
+ return entry->bufptr;
+ }
+--
+1.8.3.1
+
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 34f1e69..f1538f6 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -82,6 +82,8 @@ Patch301: kexec-tools-2.0.4-makedumpfile-Add-vmap_area_list-definition-for-ppc-p
Patch601: kexec-tools-2.0.3-disable-kexec-test.patch
Patch604: kexec-tools-2.0.3-build-makedumpfile-eppic-shared-object.patch
Patch605: kexec-tools-2.0.4-makedumpfile-PATCH-Support-newer-kernels.patch
+Patch606: kexec-tools-2.0.4-makedumpfile-cache-Allocate-buffers-at-initialization-t.patch
+Patch607: kexec-tools-2.0.4-makedumpfile-cache-Reuse-entry-in-pending-list.patch
%description
kexec-tools provides /sbin/kexec binary that facilitates a new
@@ -117,6 +119,8 @@ tar -z -x -v -f %{SOURCE19}
%patch001 -p1
%patch002 -p1
%patch003 -p1
+%patch606 -p1
+%patch607 -p1
tar -z -x -v -f %{SOURCE13}
--
1.8.3.1