This patch allows a machine to read a dump when that dump was taken on
a machine with a larger page size.
e.g. we had a dump of a 64k pagesize system, and ran crash on a
machine with a 16k pagesize.
Diffed against crash-4.0-7.6
Signed-off-by: Cliff Wickman <cpw(a)sgi.com>
---
diskdump.c | 25 +++++++++++++++++++------
tools.c | 2 ++
2 files changed, 21 insertions(+), 6 deletions(-)
Index: crash-4.0-7.6.ia64/diskdump.c
===================================================================
--- crash-4.0-7.6.ia64.orig/diskdump.c
+++ crash-4.0-7.6.ia64/diskdump.c
@@ -107,7 +107,7 @@ static int read_dump_header(char *file)
struct disk_dump_sub_header *sub_header = NULL;
struct kdump_sub_header *sub_header_kdump = NULL;
int bitmap_len;
- const int block_size = (int)sysconf(_SC_PAGESIZE);
+ int block_size = (int)sysconf(_SC_PAGESIZE);
off_t offset;
const off_t failed = (off_t)-1;
ulong pfn;
@@ -165,12 +165,25 @@ static int read_dump_header(char *file)
machine_type_mismatch(file, "PPC64", NULL, 0))
goto err;
- if (header->block_size != block_size) {
- error(INFO, "%s: block size in the dump header does not match"
- " with system page size\n",
- DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
- goto err;
+ /*
+ * Up to here, the header was assumed to be one page in size.
+ * We checked utsname and signature, which are up front in the
+ * header. But all of the task array may not have been entirely
+ * read if the executing machines's page size is smaller than that
+ * of the dumped machine.
+ * Re-read the entire header if its block_size is bigger than the
+ * executing machine's page size.
+ */
+ if (header->block_size > block_size) {
+ block_size = header->block_size;
+ free(header);
+ if ((header = malloc(block_size)) == NULL)
+ error(FATAL,
+ "diskdump / compressed kdump: cannot malloc block_size buffer\n");
+ lseek(dd->dfd, 0, SEEK_SET);
+ read(dd->dfd, header, block_size);
}
+
dd->block_size = block_size;
dd->block_shift = ffs(block_size) - 1;