Skip to contentSkip to conversation

Support Fujitsu Stand Alone Dump Format

PATCH In review HATAYAMA Daisuke 3 participants 23 messages Oct 28, 2011 – Dec 21, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover Support Fujitsu Stand Alone Dump Format

Hello Tachibana-san,

Since there's certain time until Tachibana-san's review, I made some cleanups and bugfixes to the previous version. Could you review this instead to reduce the review time?

==
The following series implements Fujitsu stand-alone dump (sadump) format support for makedumpfile, converting sadump-related formats into kdump-compressed format.

Based on makedumpfile version 1.4.0.

Here is summary of the changes.

No debug information on sadump-related formats
==============================================

Unlike other dump mechanisms, VMCORE created by sadump has NO debug information including VMCOREINFO. So, -x VMLINUX is definitely necessary.

Debug information gained from VMLINUX is used for:

1. creating VMCOREINFO dynamically, saved in resulting dumpfiles in kdump-compressed format, and

2. gaining symbolic and type information necessary to refer to ELF note information contained in VMCORE generated by kdump at crash, and to estimate phys_base value.

If no VMLINUX is specified, dumpfile with no VMCOREINFO and ELF note is generated on the current implementation.

Command-line interface change
=============================

Introduce --diskset=VMCORE to pass multiple VMCOREs in a single commnad-line input.

    makedumpfile [OPTION] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2 \
    [--diskset=VMCORE3 ..] DUMPFILE

Architectures
=============

X86 and X86_64.

On the other unsupported architectures, sadump-related source files are never compiled and linked into makedumpfile executable.

---

HATAYAMA Daisuke (14):
Add description of sadump-related formats in manual page Add description of sadump-related formts in usage information Read kexec backup region
Procees CPUs based on online ones
Generate and save VMCOREINFO and ELF note information Estimate phys_base based on linux_banner position Implement readmem() interface on sadump-related formats Initialize debug information for ELF note extraction Initialize internal data according to sadump-related formats Export helpers for bitmap table handling
Verify and read VMCORE(s) in sadump-related formats Implement command-line processing
Extend DumpInfo structure
Add sadump module header file

 Makefile       |    6 
 elf_info.c     |    2 
 makedumpfile.8 |   22 +
 makedumpfile.c |  455 +++++++++++--
 makedumpfile.h |  207 ++++++
 print_info.c   |   10 
 sadump_info.c  | 1945 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |  165 +++++
 sadump_mod.h   |  186 +++++
 9 files changed, 2907 insertions(+), 91 deletions(-)
 create mode 100644 sadump_info.c
 create mode 100644 sadump_info.h
 create mode 100644 sadump_mod.h
Signature · 7 lines
Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#1 lore raw

PATCH v2 1/14 Add sadump module header file

This header contains definitions of sadump-related dump format headers. These datatype is handled in sadump module, introduced later as sadump_info.c, only.

---

 Makefile     |    2 -
 sadump_mod.h |  174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 175 insertions(+), 1 deletions(-)
 create mode 100644 sadump_mod.h
Makefile +1 -1
index d643d2b..f7f22e5 100644
@@ -23,7 +23,7 @@ CFLAGS += -m64
 CFLAGS_ARCH += -m64
 endif
 
-SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h
+SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h
 SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c
 OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o
 SRC_ARCH = arch/arm.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c
sadump_mod.h new file +174 -0

174 lines not on this page · raw message

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#2 lore raw

PATCH v2 2/14 Extend DumpInfo structure

In reply to HATAYAMA Daisuke

Two members, flag_sadump_diskset and flag_sadump, are introduced. flag_sadump_diskset is true if --diskset=VMCORE is specified one or more times. flag_sadump has the corresponding value of type enum sadump_format_type if VMCORE(s) is in sadump-related formats.

---

 makedumpfile.h |    7 +++++++
 sadump_mod.h   |   10 ++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)
makedumpfile.h +7 -0
index f0e5da8..dee0a68 100644
@@ -34,6 +34,7 @@
 #include "common.h"
 #include "dwarf_info.h"
 #include "diskdump_mod.h"
+#include "sadump_mod.h"
 
 /*
  * Result of command
@@ -894,6 +895,12 @@ struct DumpInfo {
 	 */
 	unsigned long long split_start_pfn;  
 	unsigned long long split_end_pfn;  
+
+	/*
+	 * sadump info:
+	 */
+	int flag_sadump_diskset;
+	enum sadump_format_type flag_sadump;         /* sadump format type */
 };
 extern struct DumpInfo		*info;
 
sadump_mod.h +10 -0
index 98f5dd1..3385123 100644
@@ -171,4 +171,14 @@ struct sadump_media_header {
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
 
+/*
+ * Type of sadump related formats
+ */
+enum sadump_format_type {
+	SADUMP_UNKNOWN = 0,
+	SADUMP_SINGLE_PARTITION,
+	SADUMP_DISKSET,
+	SADUMP_MEDIA_BACKUP
+};
+
 #endif /* _SADUMP_MOD_H */

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#3 lore raw

PATCH v2 3/14 Implement command-line processing

In reply to HATAYAMA Daisuke

Introduce new long option --diskset=VMCORE, which is used for specifying multiple VMCORE(s) generated on sadump diskset configuration. --diskset and --split options can be specified at the same time.

---

 Makefile       |    6 ++--
 makedumpfile.c |   39 ++++++++++++++++++++++++----
 sadump_info.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   61 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 176 insertions(+), 8 deletions(-)
 create mode 100644 sadump_info.c
 create mode 100644 sadump_info.h
Makefile +3 -3
index f7f22e5..9b3ee9f 100644
@@ -23,9 +23,9 @@ CFLAGS += -m64
 CFLAGS_ARCH += -m64
 endif
 
-SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h
-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c
-OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o
+SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h
+SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c
+OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o sadump_info.o
 SRC_ARCH = arch/arm.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c
 OBJ_ARCH = arch/arm.o arch/x86.o arch/x86_64.o arch/ia64.o arch/ppc64.o arch/s390x.o
 
makedumpfile.c +34 -5
index 7b7c266..8a3a3d3 100644
@@ -18,6 +18,7 @@
 #include "dwarf_info.h"
 #include "elf_info.h"
 #include "erase_info.h"
+#include "sadump_info.h"
 #include <sys/time.h>
 
 struct symbol_table	symbol_table;
@@ -6500,20 +6501,34 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
 	if (info->name_filterconfig && !info->name_vmlinux)
 		return FALSE;
 
+	if (info->flag_sadump_diskset && !sadump_is_supported_arch())
+		return FALSE;
+
 	if ((argc == optind + 2) && !info->flag_flatten
-				 && !info->flag_split) {
+				 && !info->flag_split
+				 && !info->flag_sadump_diskset) {
 		/*
 		 * Parameters for creating the dumpfile from vmcore.
 		 */
 		info->name_memory   = argv[optind];
 		info->name_dumpfile = argv[optind+1];
 
-	} else if ((argc > optind + 2) && info->flag_split) {
+	} else if (info->flag_split && (info->flag_sadump_diskset
+					? (argc >= optind + 2)
+					: (argc > optind + 2))) {
+		int num_vmcore;
+
 		/*
 		 * Parameters for creating multiple dumpfiles from vmcore.
 		 */
-		info->num_dumpfile = argc - optind - 1;
-		info->name_memory  = argv[optind];
+		if (info->flag_sadump_diskset) {
+			num_vmcore = 0;
+			info->name_memory = sadump_head_disk_name_memory();
+		} else {
+			num_vmcore = 1;
+			info->name_memory = argv[optind];
+		}
+		info->num_dumpfile = argc - optind - num_vmcore;
 
 		if (info->flag_elf_dumpfile) {
 			MSG("Options for splitting dumpfile cannot be used with Elf format.\n");
@@ -6526,7 +6541,15 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
 			return FALSE;
 		}
 		for (i = 0; i < info->num_dumpfile; i++)
-			SPLITTING_DUMPFILE(i) = argv[optind + 1 + i];
+			SPLITTING_DUMPFILE(i) = argv[optind + num_vmcore + i];
+
+	} else if ((argc == optind + 1) && !info->flag_split
+					&& info->flag_sadump_diskset) {
+		info->name_dumpfile = argv[optind];
+		info->name_memory = sadump_head_disk_name_memory();
+
+		DEBUG_MSG("name_dumpfile: %s\n", info->name_dumpfile);
+		DEBUG_MSG("name_memory: %s\n", info->name_memory);
 
 	} else if ((argc == optind + 1) && info->flag_flatten) {
 		/*
@@ -6594,6 +6617,7 @@ static struct option longopts[] = {
 	{"dump-dmesg", no_argument, NULL, 'M'}, 
 	{"config", required_argument, NULL, 'C'},
 	{"help", no_argument, NULL, 'h'},
+	{"diskset", required_argument, NULL, 'k'},
 	{0, 0, 0, 0}
 };
 
@@ -6661,6 +6685,11 @@ main(int argc, char *argv[])
 			info->flag_read_vmcoreinfo = 1;
 			info->name_vmcoreinfo = optarg;
 			break;
+		case 'k':
+			if (!sadump_add_diskset_info(optarg))
+				goto out;
+			info->flag_sadump_diskset = 1;
+			break;
 		case 'm':
 			message_level = atoi(optarg);
 			break;
sadump_info.c new file +78 -0

78 lines not on this page · raw message

sadump_info.h new file +61 -0

61 lines not on this page · raw message

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#4 lore raw

PATCH v2 4/14 Verify and read VMCORE(s) in sadump-related formats

In reply to HATAYAMA Daisuke

Try to read VMCORE(s) as sadump-related formats: single partition, diskset or media backup and verify their header information. If the VMCORE(s) doesn't belong to each of them, the check continues to checking of ELF format.

---

 makedumpfile.c |   17 +-
 sadump_info.c  |  480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   10 +
 3 files changed, 500 insertions(+), 7 deletions(-)
makedumpfile.c +11 -6
index 8a3a3d3..7057009 100644
@@ -628,11 +628,16 @@ open_dump_memory(void)
 	if (status == TRUE) {
 		info->flag_refiltering = TRUE;
 		return get_kdump_compressed_header_info(info->name_memory);
-	} else if (status == FALSE) {
-		return TRUE;
-	} else {
-		return FALSE;
 	}
+
+	status = check_and_get_sadump_header_info(info->name_memory);
+	if (status == TRUE)
+		return TRUE;
+
+	if (status == ERROR)
+		return TRUE;
+
+	return FALSE;
 }
 
 int
@@ -3007,7 +3012,7 @@ dump_dmesg()
 	if (!open_files_for_creating_dumpfile())
 		return FALSE;
 
-	if (!info->flag_refiltering) {
+	if (!info->flag_refiltering && !info->flag_sadump) {
 		if (!get_elf_info(info->fd_memory, info->name_memory))
 			return FALSE;
 	}
@@ -5757,7 +5762,7 @@ create_dumpfile(void)
 	if (!open_files_for_creating_dumpfile())
 		return FALSE;
 
-	if (!info->flag_refiltering) {
+	if (!info->flag_refiltering && !info->flag_sadump) {
 		if (!get_elf_info(info->fd_memory, info->name_memory))
 			return FALSE;
 	}
sadump_info.c +479 -1

503 lines not on this page · raw message

sadump_info.h +10 -0
index 863956d..c54d29f 100644
@@ -24,6 +24,7 @@
 
 #if defined(__x86__) || defined(__x86_64__)
 
+int check_and_get_sadump_header_info(char *filename);
 int sadump_add_diskset_info(char *name_memory);
 char *sadump_head_disk_name_memory(void);
 void free_sadump_info(void);
@@ -35,6 +36,15 @@ static inline int sadump_is_supported_arch(void)
 
 #else
 
+static inline int check_and_get_sadump_header_info(char *filename)
+{
+	info->flag_sadump = SADUMP_UNKNOWN;
+
+	DEBUG_MSG("sadump: unsupported architecture\n");
+
+	return TRUE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#5 lore raw

PATCH v2 5/14 Export helpers for bitmap table handling

In reply to HATAYAMA Daisuke

sadump-related formats and kdump-compressed format is similar in structure. In particular, both have exactly the same in bitmap. So reuse two helper functions, is_on() and is_dumpable(), in sadump module.

---

 makedumpfile.c |   22 ----------------------
 makedumpfile.h |   24 ++++++++++++++++++++++++
 2 files changed, 24 insertions(+), 22 deletions(-)
makedumpfile.c +0 -22
index 7057009..96faf60 100644
@@ -2543,28 +2543,6 @@ clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn)
 }
 
 static inline int
-is_on(char *bitmap, int i)
-{
-	return bitmap[i>>3] & (1 << (i & 7));
-}
-
-static inline int
-is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
-{
-	off_t offset;
-	if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
-		offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
-		lseek(bitmap->fd, offset, SEEK_SET);
-		read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
-		if (pfn == 0)
-			bitmap->no_block = 0;
-		else
-			bitmap->no_block = pfn/PFN_BUFBITMAP;
-	}
-	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
-}
-
-static inline int
 is_in_segs(unsigned long long paddr)
 {
 	if (info->flag_refiltering) {
makedumpfile.h +24 -0
index dee0a68..17ec590 100644
@@ -56,6 +56,8 @@ enum {
 	FLATMEM
 };
 
+int get_mem_type(void);
+
 /*
  * Page flags
  *
@@ -1244,4 +1246,26 @@ int get_xen_info_ia64(void);
 #define get_xen_info_arch(X) FALSE
 #endif	/* s390x */
 
+static inline int
+is_on(char *bitmap, int i)
+{
+	return bitmap[i>>3] & (1 << (i & 7));
+}
+
+static inline int
+is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
+{
+	off_t offset;
+	if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
+		offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
+		lseek(bitmap->fd, offset, SEEK_SET);
+		read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
+		if (pfn == 0)
+			bitmap->no_block = 0;
+		else
+			bitmap->no_block = pfn/PFN_BUFBITMAP;
+	}
+	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
+}
+
 #endif /* MAKEDUMPFILE_H */

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#6 lore raw

PATCH v2 6/14 Initialize internal data according to sadump-related formats

In reply to HATAYAMA Daisuke

Set page_size, nr_cpus and time stamp. Also, initialize bitmap table in the same way as initialize_bitmap_memory() for kdump-compressed format.

---

 makedumpfile.c |   28 +++++++++++
 sadump_info.c  |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   36 ++++++++++++++
 sadump_mod.h   |    2 +
 4 files changed, 210 insertions(+), 0 deletions(-)
makedumpfile.c +28 -0
index 96faf60..c5ea9ce 100644
@@ -119,6 +119,12 @@ get_max_mapnr(void)
 		info->max_mapnr = info->dh_memory->max_mapnr;
 		return TRUE;
 	}
+
+	if (info->flag_sadump) {
+		info->max_mapnr = sadump_get_max_mapnr();
+		return TRUE;
+	}
+
 	max_paddr = get_max_paddr();
 	info->max_mapnr = paddr_to_pfn(max_paddr);
 
@@ -2305,6 +2311,28 @@ initial(void)
 		if (!initialize_bitmap_memory())
 			return FALSE;
 
+	} else if (info->flag_sadump) {
+		int nr_cpus;
+
+		if (info->flag_elf_dumpfile) {
+			MSG("'-E' option is disable, ");
+			MSG("because %s is sadump %s format.\n",
+			    info->name_memory, sadump_format_type_name());
+			return FALSE;
+		}
+
+		set_page_size(sadump_page_size());
+
+		if (!sadump_initialize_bitmap_memory())
+			return FALSE;
+
+		if (!sadump_get_nr_cpus(&nr_cpus))
+			return FALSE;
+
+		set_nr_cpus(nr_cpus);
+
+		(void) sadump_set_timestamp(&info->timestamp);
+
 	} else if (!get_phys_base())
 		return FALSE;
 
sadump_info.c +144 -0

174 lines not on this page · raw message

sadump_info.h +36 -0
index c54d29f..0a04141 100644
@@ -25,8 +25,14 @@
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);
+int sadump_initialize_bitmap_memory(void);
+int sadump_get_nr_cpus(int *nr_cpus);
+int sadump_set_timestamp(struct timeval *ts);
+unsigned long long sadump_get_max_mapnr(void);
 int sadump_add_diskset_info(char *name_memory);
+long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
+char *sadump_format_type_name(void);
 void free_sadump_info(void);
 
 static inline int sadump_is_supported_arch(void)
@@ -45,17 +51,47 @@ static inline int check_and_get_sadump_header_info(char *filename)
 	return TRUE;
 }
 
+static inline int sadump_initialize_bitmap_memory(void)
+{
+	return FALSE;
+}
+
+static inline int sadump_get_nr_cpus(int *nr_cpus)
+{
+	return 0;
+}
+
+static inline int sadump_set_timestamp(struct timeval *ts)
+{
+	return FALSE;
+}
+
+static inline unsigned long long sadump_get_max_mapnr(void)
+{
+	return 0;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;
 }
 
+static inline long sadump_page_size(void)
+{
+	return 0;
+}
+
 static inline char *
 sadump_head_disk_name_memory(void)
 {
 	return NULL;
 }
 
+static inline char *sadump_format_type_name(void)
+{
+	return NULL;
+}
+
 static inline void free_sadump_info(void)
 {
 	return;
sadump_mod.h +2 -0
index 3385123..efd059f 100644
@@ -169,6 +169,8 @@ struct sadump_media_header {
 	char reserve[4044];	// reserve feild
 };
 
+#define SADUMP_PF_SECTION_NUM 4096
+
 #endif /* defined(__x86__) && defined(__x86_64__) */
 
 /*

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#7 lore raw

PATCH v2 7/14 Initialize debug information for ELF note extraction

In reply to HATAYAMA Daisuke

Initialize symbol and type information for acessing VMCORE(s) data.

Note that there's vmlinux not including data for user_regs_struct type. In such case, we use the actual offset size calculated using offsetof().

---

 makedumpfile.c |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |  130 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+), 0 deletions(-)
makedumpfile.c +168 -0
index c5ea9ce..5ceb986 100644
@@ -19,6 +19,7 @@
 #include "elf_info.h"
 #include "erase_info.h"
 #include "sadump_info.h"
+#include <stddef.h>
 #include <sys/time.h>
 
 struct symbol_table	symbol_table;
@@ -809,6 +810,19 @@ get_symbol_info(void)
 	SYMBOL_INIT(log_end, "log_end");
 	SYMBOL_INIT(max_pfn, "max_pfn");
 	SYMBOL_INIT(modules, "modules");
+	SYMBOL_INIT(linux_banner, "linux_banner");
+	SYMBOL_INIT(bios_cpu_apicid, "bios_cpu_apicid");
+	SYMBOL_INIT(x86_bios_cpu_apicid, "x86_bios_cpu_apicid");
+	if (SYMBOL(x86_bios_cpu_apicid) == NOT_FOUND_SYMBOL)
+		SYMBOL_INIT(x86_bios_cpu_apicid,
+			    "per_cpu__x86_bios_cpu_apicid");
+	SYMBOL_INIT(x86_bios_cpu_apicid_early_ptr,
+		    "x86_bios_cpu_apicid_early_ptr");
+	SYMBOL_INIT(x86_bios_cpu_apicid_early_map,
+		    "x86_bios_cpu_apicid_early_map");
+	SYMBOL_INIT(crash_notes, "crash_notes");
+	SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
+	SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -818,6 +832,8 @@ get_symbol_info(void)
 		SYMBOL_ARRAY_LENGTH_INIT(mem_section, "mem_section");
 	if (SYMBOL(node_memblk) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_LENGTH_INIT(node_memblk, "node_memblk");
+	if (SYMBOL(__per_cpu_offset) != NOT_FOUND_SYMBOL)
+		SYMBOL_ARRAY_LENGTH_INIT(__per_cpu_offset, "__per_cpu_offset");
 
 	return TRUE;
 }
@@ -934,6 +950,158 @@ get_structure_info(void)
 
 	TYPEDEF_SIZE_INIT(nodemask_t, "nodemask_t");
 
+	SIZE_INIT(percpu_data, "percpu_data");
+
+	/*
+	 * Get offset of the elf_prstatus members.
+	 */
+	SIZE_INIT(elf_prstatus, "elf_prstatus");
+	OFFSET_INIT(elf_prstatus.pr_reg, "elf_prstatus", "pr_reg");
+
+	/*
+	 * Get offset of the user_regs_struct members.
+	 */
+	SIZE_INIT(user_regs_struct, "user_regs_struct");
+
+#ifdef __x86__
+	if (SIZE(user_regs_struct) != NOT_FOUND_STRUCTURE) {
+		OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "bx");
+		OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "cx");
+		OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "dx");
+		OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "si");
+		OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "di");
+		OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "bp");
+		OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "ax");
+		OFFSET_INIT(user_regs_struct.ds, "user_regs_struct", "ds");
+		OFFSET_INIT(user_regs_struct.es, "user_regs_struct", "es");
+		OFFSET_INIT(user_regs_struct.fs, "user_regs_struct", "fs");
+		OFFSET_INIT(user_regs_struct.gs, "user_regs_struct", "gs");
+		OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct",
+			    "orig_ax");
+		OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "ip");
+		OFFSET_INIT(user_regs_struct.cs, "user_regs_struct", "cs");
+		OFFSET_INIT(user_regs_struct.flags, "user_regs_struct",
+			    "flags");
+		OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "sp");
+		OFFSET_INIT(user_regs_struct.ss, "user_regs_struct", "ss");
+
+		if (OFFSET(user_regs_struct.bx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "ebx");
+		if (OFFSET(user_regs_struct.cx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "ecx");
+		if (OFFSET(user_regs_struct.dx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "edx");
+		if (OFFSET(user_regs_struct.si) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "esi");
+		if (OFFSET(user_regs_struct.di) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "edi");
+		if (OFFSET(user_regs_struct.bp) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "ebp");
+		if (OFFSET(user_regs_struct.ax) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "eax");
+		if (OFFSET(user_regs_struct.orig_ax) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct", "orig_eax");
+		if (OFFSET(user_regs_struct.ip) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "eip");
+		if (OFFSET(user_regs_struct.flags) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.flags, "user_regs_struct", "eflags");
+		if (OFFSET(user_regs_struct.sp) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "esp");
+	} else {
+		/*
+		 * Note: Sometimes kernel debuginfo doesn't contain
+		 * user_regs_struct structure information. Instead, we
+		 * take offsets from actual datatype.
+		 */
+		OFFSET(user_regs_struct.bx) = offsetof(struct user_regs_struct, bx);
+		OFFSET(user_regs_struct.cx) = offsetof(struct user_regs_struct, cx);
+		OFFSET(user_regs_struct.dx) = offsetof(struct user_regs_struct, dx);
+		OFFSET(user_regs_struct.si) = offsetof(struct user_regs_struct, si);
+		OFFSET(user_regs_struct.di) = offsetof(struct user_regs_struct, di);
+		OFFSET(user_regs_struct.bp) = offsetof(struct user_regs_struct, bp);
+		OFFSET(user_regs_struct.ax) = offsetof(struct user_regs_struct, ax);
+		OFFSET(user_regs_struct.ds) = offsetof(struct user_regs_struct, ds);
+		OFFSET(user_regs_struct.es) = offsetof(struct user_regs_struct, es);
+		OFFSET(user_regs_struct.fs) = offsetof(struct user_regs_struct, fs);
+		OFFSET(user_regs_struct.gs) = offsetof(struct user_regs_struct, gs);
+		OFFSET(user_regs_struct.orig_ax) = offsetof(struct user_regs_struct, orig_ax);
+		OFFSET(user_regs_struct.ip) = offsetof(struct user_regs_struct, ip);
+		OFFSET(user_regs_struct.cs) = offsetof(struct user_regs_struct, cs);
+		OFFSET(user_regs_struct.flags) = offsetof(struct user_regs_struct, flags);
+		OFFSET(user_regs_struct.sp) = offsetof(struct user_regs_struct, sp);
+		OFFSET(user_regs_struct.ss) = offsetof(struct user_regs_struct, ss);
+	}
+#endif /* __x86__ */
+
+#ifdef __x86_64__
+	if (SIZE(user_regs_struct) != NOT_FOUND_STRUCTURE) {
+		OFFSET_INIT(user_regs_struct.r15, "user_regs_struct", "r15");
+		OFFSET_INIT(user_regs_struct.r14, "user_regs_struct", "r14");
+		OFFSET_INIT(user_regs_struct.r13, "user_regs_struct", "r13");
+		OFFSET_INIT(user_regs_struct.r12, "user_regs_struct", "r12");
+		OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "bp");
+		OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "bx");
+		OFFSET_INIT(user_regs_struct.r11, "user_regs_struct", "r11");
+		OFFSET_INIT(user_regs_struct.r10, "user_regs_struct", "r10");
+		OFFSET_INIT(user_regs_struct.r9, "user_regs_struct", "r9");
+		OFFSET_INIT(user_regs_struct.r8, "user_regs_struct", "r8");
+		OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "ax");
+		OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "cx");
+		OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "dx");
+		OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "si");
+		OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "di");
+		OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct",
+			    "orig_ax");
+		OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "ip");
+		OFFSET_INIT(user_regs_struct.cs, "user_regs_struct", "cs");
+		OFFSET_INIT(user_regs_struct.flags, "user_regs_struct",
+			    "flags");
+		OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "sp");
+		OFFSET_INIT(user_regs_struct.ss, "user_regs_struct", "ss");
+		OFFSET_INIT(user_regs_struct.fs_base, "user_regs_struct",
+			    "fs_base");
+		OFFSET_INIT(user_regs_struct.gs_base, "user_regs_struct",
+			    "gs_base");
+		OFFSET_INIT(user_regs_struct.ds, "user_regs_struct", "ds");
+		OFFSET_INIT(user_regs_struct.es, "user_regs_struct", "es");
+		OFFSET_INIT(user_regs_struct.fs, "user_regs_struct", "fs");
+		OFFSET_INIT(user_regs_struct.gs, "user_regs_struct", "gs");
+	} else {
+		/*
+		 * Note: Sometimes kernel debuginfo doesn't contain
+		 * user_regs_struct structure information. Instead, we
+		 * take offsets from actual datatype.
+		 */
+		OFFSET(user_regs_struct.r15) = offsetof(struct user_regs_struct, r15);
+		OFFSET(user_regs_struct.r14) = offsetof(struct user_regs_struct, r14);
+		OFFSET(user_regs_struct.r13) = offsetof(struct user_regs_struct, r13);
+		OFFSET(user_regs_struct.r12) = offsetof(struct user_regs_struct, r12);
+		OFFSET(user_regs_struct.bp) = offsetof(struct user_regs_struct, bp);
+		OFFSET(user_regs_struct.bx) = offsetof(struct user_regs_struct, bx);
+		OFFSET(user_regs_struct.r11) = offsetof(struct user_regs_struct, r11);
+		OFFSET(user_regs_struct.r10) = offsetof(struct user_regs_struct, r10);
+		OFFSET(user_regs_struct.r9) = offsetof(struct user_regs_struct, r9);
+		OFFSET(user_regs_struct.r8) = offsetof(struct user_regs_struct, r8);
+		OFFSET(user_regs_struct.ax) = offsetof(struct user_regs_struct, ax);
+		OFFSET(user_regs_struct.cx) = offsetof(struct user_regs_struct, cx);
+		OFFSET(user_regs_struct.dx) = offsetof(struct user_regs_struct, dx);
+		OFFSET(user_regs_struct.si) = offsetof(struct user_regs_struct, si);
+		OFFSET(user_regs_struct.di) = offsetof(struct user_regs_struct, di);
+		OFFSET(user_regs_struct.orig_ax) = offsetof(struct user_regs_struct, orig_ax);
+		OFFSET(user_regs_struct.ip) = offsetof(struct user_regs_struct, ip);
+		OFFSET(user_regs_struct.cs) = offsetof(struct user_regs_struct, cs);
+		OFFSET(user_regs_struct.flags) = offsetof(struct user_regs_struct, flags);
+		OFFSET(user_regs_struct.sp) = offsetof(struct user_regs_struct, sp);
+		OFFSET(user_regs_struct.ss) = offsetof(struct user_regs_struct, ss);
+		OFFSET(user_regs_struct.fs_base) = offsetof(struct user_regs_struct, fs_base);
+		OFFSET(user_regs_struct.gs_base) = offsetof(struct user_regs_struct, gs_base);
+		OFFSET(user_regs_struct.ds) = offsetof(struct user_regs_struct, ds);
+		OFFSET(user_regs_struct.es) = offsetof(struct user_regs_struct, es);
+		OFFSET(user_regs_struct.fs) = offsetof(struct user_regs_struct, fs);
+		OFFSET(user_regs_struct.gs) = offsetof(struct user_regs_struct, gs);
+	}
+#endif /* __x86_64__ */
+
 	return TRUE;
 }
 
makedumpfile.h +130 -0

158 lines not on this page · raw message

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#8 lore raw

PATCH v2 8/14 Implement readmem() interface on sadump-related formats

In reply to HATAYAMA Daisuke

Very similar to the ones in kdump-compressed format.

---

 makedumpfile.c |    8 +++
 sadump_info.c  |  145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   13 +++++
 3 files changed, 165 insertions(+), 1 deletions(-)
makedumpfile.c +7 -1
index 5ceb986..205d3de 100644
@@ -346,6 +346,9 @@ readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
 	if (info->flag_refiltering)
 		return readpmem_kdump_compressed(paddr, bufptr, read_size);
 
+	if (info->flag_sadump)
+		return readpmem_sadump(paddr, bufptr, read_size);
+
 	if (!(offset = paddr_to_offset(paddr))) {
 		ERRMSG("Can't convert a physical address(%llx) to offset.\n",
 		    paddr);
@@ -3436,6 +3439,9 @@ create_1st_bitmap(void)
 	if (info->flag_refiltering)
 		return copy_1st_bitmap_from_memory();
 
+	if (info->flag_sadump)
+		return sadump_copy_1st_bitmap_from_memory();
+
 	/*
 	 * At first, clear all the bits on the 1st-bitmap.
 	 */
@@ -4535,7 +4541,7 @@ read_pfn(unsigned long long pfn, unsigned char *buf)
 	size_t size1, size2;
 
 	paddr = pfn_to_paddr(pfn);
-	if (info->flag_refiltering) {
+	if (info->flag_refiltering || info->flag_sadump) {
 		if (!readmem(PADDR, paddr, buf, info->page_size)) {
 			ERRMSG("Can't get the page data.\n");
 			return FALSE;
sadump_info.c +145 -0

163 lines not on this page · raw message

sadump_info.h +13 -0
index 0a04141..b6b9cdd 100644
@@ -25,10 +25,12 @@
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);
+int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_initialize_bitmap_memory(void);
 int sadump_get_nr_cpus(int *nr_cpus);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
+int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
 int sadump_add_diskset_info(char *name_memory);
 long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
@@ -51,6 +53,11 @@ static inline int check_and_get_sadump_header_info(char *filename)
 	return TRUE;
 }
 
+static inline int sadump_copy_1st_bitmap_from_memory(void)
+{
+	return FALSE;
+}
+
 static inline int sadump_initialize_bitmap_memory(void)
 {
 	return FALSE;
@@ -71,6 +78,12 @@ static inline unsigned long long sadump_get_max_mapnr(void)
 	return 0;
 }
 
+static inline int readpmem_sadump(unsigned long long paddr,
+				  void *bufptr, size_t size)
+{
+	return FALSE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#9 lore raw

PATCH v2 9/14 Estimate phys_base based on linux_banner position

In reply to HATAYAMA Daisuke

sadump doesn't save phys_base, so we must estimate it in any way. Here we borrow the method in crash utility that we search a certain range of addresses for linux_banner symbol value.

---

 makedumpfile.c |   12 ++++++++++++
 sadump_info.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   13 +++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)
makedumpfile.c +12 -0
index 205d3de..6e9dd83 100644
@@ -2504,6 +2504,15 @@ initial(void)
 
 		(void) sadump_set_timestamp(&info->timestamp);
 
+		/*
+		 * NOTE: phys_base is never saved by sadump and so
+		 * must be computed in some way. We here choose the
+		 * way of looking at linux_banner. See
+		 * sadump_virt_phys_base(). The processing is
+		 * postponed until debug information becomes
+		 * available.
+		 */
+
 	} else if (!get_phys_base())
 		return FALSE;
 
@@ -2579,6 +2588,9 @@ out:
 		return FALSE;
 
 	if (debug_info) {
+		if (info->flag_sadump)
+			(void) sadump_virt_phys_base();
+
 		if (!get_machdep_info())
 			return FALSE;
 
sadump_info.c +47 -0

59 lines not on this page · raw message

sadump_info.h +13 -0
index b6b9cdd..401b769 100644
@@ -22,6 +22,19 @@
 
 #include "makedumpfile.h"
 
+#ifdef __x86_64__
+
+int sadump_virt_phys_base(void);
+
+#else
+
+static inline int sadump_virt_phys_base(void)
+{
+	return TRUE;
+}
+
+#endif
+
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#10 lore raw

PATCH v2 10/14 Generate and save VMCOREINFO and ELF note information

In reply to HATAYAMA Daisuke

Retrieve VMCOREINFO from VMLINUX and ELF note information from VMCORE(s) and save them in generated DUMPFILE.

ELF note information is NT_PRSTATUS only. If crash_notes is NULL, indicating kdump has not saved register values, save SMRAM CPU STATE values. If crash_notes is not NULL, indicating kdump has saved register values at crash, then save the register values in crash_notes.

---

 elf_info.c     |    2 
 makedumpfile.c |  103 ++++---
 makedumpfile.h |    2 
 sadump_info.c  |  823 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   26 ++
 5 files changed, 913 insertions(+), 43 deletions(-)
elf_info.c +1 -1
index 114dd05..48f8510 100644
@@ -760,7 +760,7 @@ get_nr_cpus(void)
 int
 has_pt_note(void)
 {
-	if (offset_pt_note_memory && size_pt_note_memory)
+	if (offset_pt_note_memory || size_pt_note_memory)
 		return TRUE;
 	return FALSE;
 }
makedumpfile.c +61 -42

129 lines not on this page · raw message

makedumpfile.h +2 -0
index 433bc49..67a6b4f 100644
@@ -1328,6 +1328,8 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
 }
 
+void write_vmcoreinfo_data(void);
+
 #ifdef __x86__
 
 struct user_regs_struct {
sadump_info.c +823 -0

882 lines not on this page · raw message

sadump_info.h +26 -0
index 401b769..c1f948f 100644
@@ -44,7 +44,12 @@ int sadump_get_nr_cpus(int *nr_cpus);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
 int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
+int sadump_check_debug_info(void);
+int sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size);
+int sadump_generate_elf_note_from_dumpfile(void);
+int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_add_diskset_info(char *name_memory);
+int sadump_read_elf_note(char *buf, size_t size_note);
 long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
 char *sadump_format_type_name(void);
@@ -97,11 +102,32 @@ static inline int readpmem_sadump(unsigned long long paddr,
 	return FALSE;
 }
 
+static inline int sadump_check_debug_info(void)
+{
+	return FALSE;
+}
+
+static inline int
+sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size)
+{
+	return FALSE;
+}
+
+static inline int sadump_generate_elf_note_from_dumpfile(void)
+{
+	return FALSE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;
 }
 
+static inline int sadump_read_elf_note(char *buf, size_t size_note)
+{
+	return FALSE;
+}
+
 static inline long sadump_page_size(void)
 {
 	return 0;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#11 lore raw

Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information

Hi Hatayama-san,

Quoted 7 lines

[snipped]

elf_info.c +0 -0
index 114dd05..48f8510 100644

elf_info.c get_nr_cpus(void) · line 766

Quoted 8 lines
elf_info.c +1 -1
@@ -760,7 +760,7 @@ get_nr_cpus(void)
 int
 has_pt_note(void)
 {
-	if (offset_pt_note_memory && size_pt_note_memory)
+	if (offset_pt_note_memory || size_pt_note_memory)
 		return TRUE;
 	return FALSE;
 }

I have a question.
In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?

Thanks.
Atsushi Kumagai

Quoted 19 lines · On Fri, 28 Oct 2011 18:48:58 +0900 HATAYAMA Daisuke…

Retrieve VMCOREINFO from VMLINUX and ELF note information from VMCORE(s) and save them in generated DUMPFILE.

ELF note information is NT_PRSTATUS only. If crash_notes is NULL, indicating kdump has not saved register values, save SMRAM CPU STATE values. If crash_notes is not NULL, indicating kdump has saved register values at crash, then save the register values in crash_notes.

---

 elf_info.c     |    2 
 makedumpfile.c |  103 ++++---
 makedumpfile.h |    2 
 sadump_info.c  |  823 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   26 ++
 5 files changed, 913 insertions(+), 43 deletions(-)
Quoted 6 lines

[snipped]

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#12 lore raw

Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information

Hello Kumagai-san,

From: Atsushi Kumagai <[email protected]>
Subject: Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
Date: Tue, 20 Dec 2011 17:18:12 +0900

Quoted 4 lines

Hi Hatayama-san,

Quoted 2 lines

[snipped]

Quoted 17 lines

elf_info.c get_nr_cpus(void) · line 766

Quoted 13 lines
elf_info.c +1 -1
index 114dd05..48f8510 100644
@@ -760,7 +760,7 @@ get_nr_cpus(void)
 int
 has_pt_note(void)
 {
-	if (offset_pt_note_memory && size_pt_note_memory)
+	if (offset_pt_note_memory || size_pt_note_memory)
 		return TRUE;
 	return FALSE;
 }

I have a question.
In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?

Thanks for your reviewing.

On sadump processing, offset_pt_note_memory represents file offset to a temporary file created specifically for writing PT_NOTE section. So offset_pt_note_memory is always 0. Its file pointer is set to struct sadump_info::file_elf_note. Please look at the end of sadump_generate_elf_note_from_dumpfile().

On the other hand, on both ELF and kdump-compressed format, PT_NOTE section is always located in the middle of the vmcores. On either formats, there's always another header before the PT_NOTE section: on ELF, ELF header, and on kdump-compressed format, at least. So offset_pt_note_memory is always strictly greater than 0 on these formats.

If condition of has_pt_note() is not weakened in such a way, has_pt_note() amounts to always false and execution in write_kdump_header() always passes through writing oepration for PT_NOTE section.

Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#13 lore raw

Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information

Hi Hatayama-san,

Quoted 19 lines
Quoted 3 lines

I have a question.
In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?

Thanks for your reviewing.

On sadump processing, offset_pt_note_memory represents file offset to a temporary file created specifically for writing PT_NOTE section. So offset_pt_note_memory is always 0. Its file pointer is set to struct sadump_info::file_elf_note. Please look at the end of sadump_generate_elf_note_from_dumpfile().

On the other hand, on both ELF and kdump-compressed format, PT_NOTE section is always located in the middle of the vmcores. On either formats, there's always another header before the PT_NOTE section: on ELF, ELF header, and on kdump-compressed format, at least. So offset_pt_note_memory is always strictly greater than 0 on these formats.

Quoted 4 lines

If condition of has_pt_note() is not weakened in such a way, has_pt_note() amounts to always false and execution in write_kdump_header() always passes through writing oepration for PT_NOTE section.

Thank you for your explanation. I understand.
However

	if (offset_pt_note_memory || size_pt_note_memory)

seems to allow the offset != 0 and the size == 0.
Is the following fixing right?
I would like to fix has_pt_note() like this.
How about this?

- if (offset_pt_note_memory && size_pt_note_memory)
+ if (info->flag_sadump) {
+ if (size_pt_note_memory)
+ return TRUE;
+ } else if (offset_pt_note_memory && size_pt_note_memory)

			return TRUE;

Thanks.
Atsushi Kumagai

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#14 lore raw

Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information

From: Atsushi Kumagai <[email protected]>
Subject: Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
Date: Wed, 21 Dec 2011 17:22:30 +0900

Quoted 40 lines

Hi Hatayama-san,

Quoted 19 lines
Quoted 3 lines

I have a question.
In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?

Thanks for your reviewing.

On sadump processing, offset_pt_note_memory represents file offset to a temporary file created specifically for writing PT_NOTE section. So offset_pt_note_memory is always 0. Its file pointer is set to struct sadump_info::file_elf_note. Please look at the end of sadump_generate_elf_note_from_dumpfile().

On the other hand, on both ELF and kdump-compressed format, PT_NOTE section is always located in the middle of the vmcores. On either formats, there's always another header before the PT_NOTE section: on ELF, ELF header, and on kdump-compressed format, at least. So offset_pt_note_memory is always strictly greater than 0 on these formats.

Quoted 4 lines

If condition of has_pt_note() is not weakened in such a way, has_pt_note() amounts to always false and execution in write_kdump_header() always passes through writing oepration for PT_NOTE section.

Thank you for your explanation. I understand.
However

	if (offset_pt_note_memory || size_pt_note_memory)

seems to allow the offset != 0 and the size == 0.
Is the following fixing right?
I would like to fix has_pt_note() like this.
How about this?

(quoted diff) +4 -1
-	if (offset_pt_note_memory && size_pt_note_memory)
+       if (info->flag_sadump) {
+		if (size_pt_note_memory)
+			return TRUE;
+	} else if (offset_pt_note_memory && size_pt_note_memory)
Quoted 2 lines
			return TRUE;

I agree. It looks better.

Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#15 lore raw

PATCH v2 11/14 Procees CPUs based on online ones

In reply to HATAYAMA Daisuke

Assign the number of online cpus to nr_cpus member in diskset header, and create NR_PRSTATUS for each online cpu. This behaviour is sound with respect to kdump's and crash's on kdump-compressed format.

---

 makedumpfile.c |   27 +++++++++++----
 makedumpfile.h |    3 ++
 sadump_info.c  |  100 +++++++++++++++++++++++++++++++++++++++++++++-----------
 sadump_info.h  |    4 +-
 4 files changed, 106 insertions(+), 28 deletions(-)
makedumpfile.c +20 -7
index 750dcb6..44f6ee6 100644
@@ -826,6 +826,9 @@ get_symbol_info(void)
 	SYMBOL_INIT(crash_notes, "crash_notes");
 	SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
 	SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
+	SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
+	if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
+		SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -962,6 +965,13 @@ get_structure_info(void)
 	OFFSET_INIT(elf_prstatus.pr_reg, "elf_prstatus", "pr_reg");
 
 	/*
+	 * Get size of cpumask and cpumask_t.
+	 */
+	SIZE_INIT(cpumask, "cpumask");
+
+	TYPEDEF_SIZE_INIT(cpumask_t, "cpumask_t");
+
+	/*
 	 * Get offset of the user_regs_struct members.
 	 */
 	SIZE_INIT(user_regs_struct, "user_regs_struct");
@@ -2489,8 +2499,6 @@ initial(void)
 			return FALSE;
 
 	} else if (info->flag_sadump) {
-		int nr_cpus;
-
 		if (info->flag_elf_dumpfile) {
 			MSG("'-E' option is disable, ");
 			MSG("because %s is sadump %s format.\n",
@@ -2503,11 +2511,6 @@ initial(void)
 		if (!sadump_initialize_bitmap_memory())
 			return FALSE;
 
-		if (!sadump_get_nr_cpus(&nr_cpus))
-			return FALSE;
-
-		set_nr_cpus(nr_cpus);
-
 		(void) sadump_set_timestamp(&info->timestamp);
 
 		/*
@@ -2600,6 +2603,16 @@ out:
 		if (!get_machdep_info())
 			return FALSE;
 
+		if (info->flag_sadump) {
+			int online_cpus;
+
+			online_cpus = sadump_num_online_cpus();
+			if (!online_cpus)
+				return FALSE;
+
+			set_nr_cpus(online_cpus);
+		}
+
 		if (!check_release())
 			return FALSE;
 
makedumpfile.h +3 -0
index 67a6b4f..020d99c 100644
@@ -995,6 +995,7 @@ struct symbol_table {
 	unsigned long long	crash_notes;
 	unsigned long long	__per_cpu_offset;
 	unsigned long long	__per_cpu_load;
+	unsigned long long	cpu_online_mask;
 };
 
 struct size_table {
@@ -1024,6 +1025,8 @@ struct size_table {
 	long	percpu_data;
 	long	elf_prstatus;
 	long	user_regs_struct;
+	long	cpumask;
+	long	cpumask_t;
 };
 
 struct offset_table {
sadump_info.c +81 -19

161 lines not on this page · raw message

sadump_info.h +2 -2
index c1f948f..f90ea5a 100644
@@ -40,7 +40,7 @@ static inline int sadump_virt_phys_base(void)
 int check_and_get_sadump_header_info(char *filename);
 int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_initialize_bitmap_memory(void);
-int sadump_get_nr_cpus(int *nr_cpus);
+int sadump_num_online_cpus(void);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
 int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
@@ -81,7 +81,7 @@ static inline int sadump_initialize_bitmap_memory(void)
 	return FALSE;
 }
 
-static inline int sadump_get_nr_cpus(int *nr_cpus)
+static inline int sadump_num_online_cpus(void);
 {
 	return 0;
 }

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#16 lore raw

PATCH v2 12/14 Read kexec backup region

In reply to HATAYAMA Daisuke

Deal with the first 640kB memory backed up by kdump by interpreting the read request to the region as the request to the backup region that is specially prepared to preserve the original first kernel's memory situtation.

The first 640kB memory contains the data necessary for paging: PTE, for example. So, initialization must be done before trying to read memory requiring paging to read such as VMALLOC'ed data.

---

 makedumpfile.c |   45 +++++++++++----
 makedumpfile.h |   41 ++++++++++++++
 sadump_info.c  |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |    6 ++
 4 files changed, 249 insertions(+), 11 deletions(-)
makedumpfile.c +34 -11
index 44f6ee6..df82a48 100644
@@ -829,6 +829,7 @@ get_symbol_info(void)
 	SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
 	if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
 		SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
+	SYMBOL_INIT(kexec_crash_image, "kexec_crash_image");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -1115,6 +1116,23 @@ get_structure_info(void)
 	}
 #endif /* __x86_64__ */
 
+	OFFSET_INIT(kimage.segment, "kimage", "segment");
+
+	MEMBER_ARRAY_LENGTH_INIT(kimage.segment, "kimage", "segment");
+
+	SIZE_INIT(kexec_segment, "kexec_segment");
+	OFFSET_INIT(kexec_segment.mem, "kexec_segment", "mem");
+
+	OFFSET_INIT(elf64_hdr.e_phnum, "elf64_hdr", "e_phnum");
+	OFFSET_INIT(elf64_hdr.e_phentsize, "elf64_hdr", "e_phentsize");
+	OFFSET_INIT(elf64_hdr.e_phoff, "elf64_hdr", "e_phoff");
+
+	SIZE_INIT(elf64_hdr, "elf64_hdr");
+	OFFSET_INIT(elf64_phdr.p_type, "elf64_phdr", "p_type");
+	OFFSET_INIT(elf64_phdr.p_offset, "elf64_phdr", "p_offset");
+	OFFSET_INIT(elf64_phdr.p_paddr, "elf64_phdr", "p_paddr");
+	OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz");
+
 	return TRUE;
 }
 
@@ -2619,6 +2637,16 @@ out:
 		if (!get_versiondep_info())
 			return FALSE;
 
+		/*
+		 * NOTE: This must be done before refering to
+		 * VMALLOC'ed memory. The first 640kB contains data
+		 * necessary for paging, like PTE. The absence of the
+		 * region affects reading VMALLOC'ed memory such as
+		 * module data.
+		 */
+		if (info->flag_sadump)
+			sadump_kdump_backup_region_init();
+
 		if (!get_numnodes())
 			return FALSE;
 
@@ -2756,6 +2784,12 @@ set_bit_on_1st_bitmap(unsigned long long pfn)
 }
 
 int
+clear_bit_on_1st_bitmap(unsigned long long pfn)
+{
+	return set_bitmap(info->bitmap1, pfn, 0);
+}
+
+int
 clear_bit_on_2nd_bitmap(unsigned long long pfn)
 {
 	return set_bitmap(info->bitmap2, pfn, 0);
@@ -2796,17 +2830,6 @@ is_in_segs(unsigned long long paddr)
 		return FALSE;
 }
 
-static inline int
-is_zero_page(unsigned char *buf, long page_size)
-{
-	size_t i;
-
-	for (i = 0; i < page_size; i++)
-		if (buf[i])
-			return FALSE;
-	return TRUE;
-}
-
 int
 read_cache(struct cache_data *cd)
 {
makedumpfile.h +41 -0

78 lines not on this page · raw message

sadump_info.c +168 -0

190 lines not on this page · raw message

sadump_info.h +6 -0
index f90ea5a..1f74ee5 100644
@@ -54,6 +54,7 @@ long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
 char *sadump_format_type_name(void);
 void free_sadump_info(void);
+void sadump_kdump_backup_region_init(void);
 
 static inline int sadump_is_supported_arch(void)
 {
@@ -154,6 +155,11 @@ static inline int sadump_is_supported_arch(void)
 	return FALSE;
 }
 
+static inline void sadump_kdump_backup_region_init(void)
+{
+	return;
+}
+
 #endif
 
 #endif /* _SADUMP_INFO_H */

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#17 lore raw

PATCH v2 13/14 Add description of sadump-related formts in usage information

In reply to HATAYAMA Daisuke

---

 print_info.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)
print_info.c +10 -0
index 547976e..19a578b 100644
@@ -69,6 +69,11 @@ print_usage(void)
 	MSG("  # makedumpfile -g VMCOREINFO --xen-syms XEN-SYMS\n");
 	MSG("\n");
 	MSG("\n");
+	MSG("  Creating DUMPFILE from multiple VMCOREs generated on sadump diskset configuration:\n");
+	MSG("  # makedumpfile [-c] [-d DL] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2\n");
+	MSG("    [--diskset=VMCORE3 ..] DUMPFILE\n");
+	MSG("\n");
+	MSG("\n");
 	MSG("Available options:\n");
 	MSG("  [-c]:\n");
 	MSG("      Compress dump data by each page.\n");
@@ -163,6 +168,11 @@ print_usage(void)
 	MSG("      Exclude all the user domain pages from Xen kdump's VMCORE, and extract\n");
 	MSG("      the part of Xen and domain-0.\n");
 	MSG("\n");
+	MSG("  [--diskset=VMCORE]:\n");
+	MSG("      Specify multiple VMCOREs created on sadump diskset configuration the same\n");
+	MSG("      number of times as the number of VMCOREs in increasing order from left to\n");
+	MSG("      right.\n");
+	MSG("\n");
 	MSG("  [--message-level ML]:\n");
 	MSG("      Specify the message types.\n");
 	MSG("      Users can restrict output printed by specifying Message_Level (ML) with\n");

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#18 lore raw

PATCH v2 14/14 Add description of sadump-related formats in manual page

In reply to HATAYAMA Daisuke

---

 makedumpfile.8 |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)
makedumpfile.8 +22 -0
index 1da16b9..f7dfe04 100644
@@ -20,6 +20,8 @@ makedumpfile \- make a small dumpfile of kdump
 .br
 \fBmakedumpfile\fR \-\-dump-dmesg [\-x \fIVMLINUX\fR|\-i \fIVMCOREINFO\fR] \fIVMCORE\fR \fILOGFILE\fR
 .br
+\fBmakedumpfile\fR    [\fIOPTION\fR] \-x \fIVMLINUX\fR \-\-diskset=\fIVMCORE1\fR \-\-diskset=\fIVMCORE2\fR [\-\-diskset=\fIVMCORE3\fR ..] \fIDUMPFILE\fR
+.br
 .B makedumpfile
 \-h
 .br
@@ -104,6 +106,14 @@ one of dump_level 3 like the following:
 # makedumpfile \-c \-d 3 /proc/vmcore dumpfile.1
 .br
 # makedumpfile \-c \-d 31 dumpfile.1 dumpfile.2
+.PP
+makedumpfile can read \fIVMCORE\fR(s) in three kinds of sadump
+formats: single partition format, diskset format and media backup
+format, and can convert each of them into kdump-compressed format with
+filtering and compression processing. Note that for \fIVMCORE\fR(s)
+created by sadump, you always need to pass \fIVMLINUX\fR with -x
+option. Also, to pass multiple \fIVMCORE\fRs created on diskset
+configuration, you need to use --diskset option.
 
 .PP
 .SH OPTIONS
@@ -460,6 +470,18 @@ it is necessary to specfiy [\-x \fIVMLINUX\fR] or [\-i \fIVMCOREINFO\fR].
 .br
 
 .TP
+\fB\-\-diskset=VMCORE\fR
+Specify multiple \fIVMCORE\fRs created on sadump diskset configuration
+the same number of times as the number of \fIVMCORE\fRs in increasing
+order from left to right.  \fIVMCORE\fRs are assembled into a single
+\fIDUMPFILE.
+
+.br
+.B Example:
+.br
+# makedumpfile \-x vmlinux \-\-diskset=vmcore1 \-\-diskset=vmcore2 dumpfile
+
+.TP
 \fB\-D\fR
 Print debugging message.
 

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#19 lore raw
In reply to HATAYAMA Daisuke

Hi HATAYAMA-san

Thank you for updating patches.
I will review them.

Thanks.
tachibana

Quoted 72 lines · HATAYAMA Daisuke

Hello Tachibana-san,

Since there's certain time until Tachibana-san's review, I made some cleanups and bugfixes to the previous version. Could you review this instead to reduce the review time?

==
The following series implements Fujitsu stand-alone dump (sadump) format support for makedumpfile, converting sadump-related formats into kdump-compressed format.

Based on makedumpfile version 1.4.0.

Here is summary of the changes.

No debug information on sadump-related formats
==============================================

Unlike other dump mechanisms, VMCORE created by sadump has NO debug information including VMCOREINFO. So, -x VMLINUX is definitely necessary.

Debug information gained from VMLINUX is used for:

1. creating VMCOREINFO dynamically, saved in resulting dumpfiles in kdump-compressed format, and

2. gaining symbolic and type information necessary to refer to ELF note information contained in VMCORE generated by kdump at crash, and to estimate phys_base value.

If no VMLINUX is specified, dumpfile with no VMCOREINFO and ELF note is generated on the current implementation.

Command-line interface change
=============================

Introduce --diskset=VMCORE to pass multiple VMCOREs in a single commnad-line input.

    makedumpfile [OPTION] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2 \
    [--diskset=VMCORE3 ..] DUMPFILE

Architectures
=============

X86 and X86_64.

On the other unsupported architectures, sadump-related source files are never compiled and linked into makedumpfile executable.

---

HATAYAMA Daisuke (14):
Add description of sadump-related formats in manual page Add description of sadump-related formts in usage information Read kexec backup region
Procees CPUs based on online ones
Generate and save VMCOREINFO and ELF note information Estimate phys_base based on linux_banner position Implement readmem() interface on sadump-related formats Initialize debug information for ELF note extraction Initialize internal data according to sadump-related formats Export helpers for bitmap table handling
Verify and read VMCORE(s) in sadump-related formats Implement command-line processing
Extend DumpInfo structure
Add sadump module header file

Quoted 22 lines
 Makefile       |    6 
 elf_info.c     |    2 
 makedumpfile.8 |   22 +
 makedumpfile.c |  455 +++++++++++--
 makedumpfile.h |  207 ++++++
 print_info.c   |   10 
 sadump_info.c  | 1945 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |  165 +++++
 sadump_mod.h   |  186 +++++
 9 files changed, 2907 insertions(+), 91 deletions(-)
 create mode 100644 sadump_info.c
 create mode 100644 sadump_info.h
 create mode 100644 sadump_mod.h
Signature · 7 lines
Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#21 lore raw

Hi Hatayama-san,

Sorry for late reply.
Now we are executing regression tests.
If no problem will be detected, we will merge sadump patches into makedumpfile V.1.4.1 around the new year.

Thanks.
tachibana

Quoted 12 lines · HATAYAMA Daisuke

Hello Tachibana-san,

From: [email protected]
Subject: Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
Date: Fri, 28 Oct 2011 21:05:03 +0900

Quoted 6 lines

Hi HATAYAMA-san

Thank you for updating patches.
I will review them.

Quoted 9 lines
Quoted 3 lines

Thanks.
tachibana

Could you tell me the status?

Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#22 lore raw

Hello Tachibana-san,

From: [email protected]
Subject: Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
Date: Thu, 15 Dec 2011 17:55:22 +0900

Quoted 9 lines

Hi Hatayama-san,

Sorry for late reply.
Now we are executing regression tests.
If no problem will be detected, we will merge sadump patches into makedumpfile V.1.4.1 around the new year.

Thanks.
tachibana

So I'm waiting for the result.

Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec