diff options
author | Thadeu Lima de Souza Cascardo <cascardo@debian.org> | 2018-07-19 16:34:06 -0300 |
---|---|---|
committer | Thadeu Lima de Souza Cascardo <cascardo@debian.org> | 2018-07-19 16:34:06 -0300 |
commit | edad422003b3f542856d3d5dbf0fe0dc6727d4d4 (patch) | |
tree | e235c6836eb76dc59c987cd4506e60d660df6302 /IMPLEMENTATION |
Import makedumpfile_1.6.4.orig.tar.gz
[dgit import orig makedumpfile_1.6.4.orig.tar.gz]
Diffstat (limited to 'IMPLEMENTATION')
-rw-r--r-- | IMPLEMENTATION | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/IMPLEMENTATION b/IMPLEMENTATION new file mode 100644 index 0000000..589c5bf --- /dev/null +++ b/IMPLEMENTATION @@ -0,0 +1,282 @@ +* The kdump-compressed format + makedumpfile provides two DUMPFILE formats (the ELF format and the + kdump-compressed format). By default, makedumpfile makes a DUMPFILE + in the kdump-compressed format. The kdump-compressed format is readable + only with the crash utility, and it can be smaller than the ELF format + because of the compression support. + + - The file structure + File offset + +------------------------------------------+ 0x0 + | main header (struct disk_dump_header) | + |------------------------------------------+ block 1 + | sub header (struct kdump_sub_header) | + |------------------------------------------+ block 2 + | 1st-bitmap | + |------------------------------------------+ block 2 + X blocks + | 2nd-bitmap | (aligned by block) + |------------------------------------------+ block 2 + 2 * X blocks + | page header for pfn 0 (struct page_desc) | (aligned by block) + | page header for pfn 1 (struct page_desc) | + | : | + | page header for pfn Z (struct page_desc) | + |------------------------------------------| (not aligned by block) + | page data (pfn 0) | + | page data (pfn 1) | + | : | + | page data (pfn Z) | + +------------------------------------------+ offset_eraseinfo + | erase mystruct2.mystruct1.var size 4 | + | erase mystruct2.mystruct1.ptr nullify | + | erase mystruct2.mystruct.array size 100 | + +------------------------------------------+ + + + - main header + The main header of the kdump compressed format is the almost same as the + one of diskdump. This header has the following members, and the member + signature and header_version are different from diskdump. + + struct disk_dump_header { + char signature[SIG_LEN]; /* = "KDUMP " */ + int header_version; /* Dump header version */ + struct new_utsname utsname; /* copy of system_utsname */ + struct timeval timestamp; /* Time stamp */ + unsigned int status; /* Above flags */ + int block_size; /* Size of a block in byte */ + int sub_hdr_size; /* Size of arch dependent + header in blocks */ + unsigned int bitmap_blocks; /* Size of Memory bitmap in + block */ + unsigned int max_mapnr; /* = max_mapnr, OBSOLETE! + 32bit only, full 64bit + in sub header. */ + unsigned int total_ram_blocks;/* Number of blocks should be + written */ + unsigned int device_blocks; /* Number of total blocks in + * the dump device */ + unsigned int written_blocks; /* Number of written blocks */ + unsigned int current_cpu; /* CPU# which handles dump */ + int nr_cpus; /* Number of CPUs */ + struct task_struct *tasks[0]; + }; + + - sub header + The sub header of the kdump compressed format is original. This header + has the member phys_base and dump_level. The member phys_base is for + an x86_64 relocatable kernel, and the member dump_level has '-d' option's + value of makedumpfile command. + + struct kdump_sub_header { + unsigned long phys_base; + int dump_level; /* header_version 1 and later */ + int split; /* header_version 2 and later */ + unsigned long start_pfn; /* header_version 2 and later, + OBSOLETE! 32bit only, full + 64bit in start_pfn_64. */ + unsigned long end_pfn; /* header_version 2 and later, + OBSOLETE! 32bit only, full + 64bit in end_pfn_64. */ + off_t offset_vmcoreinfo;/* header_version 3 and later */ + unsigned long size_vmcoreinfo; /* header_version 3 and later */ + off_t offset_note; /* header_version 4 and later */ + unsigned long size_note; /* header_version 4 and later */ + off_t offset_eraseinfo; /* header_version 5 and later */ + unsigned long size_eraseinfo; /* header_version 5 and later */ + unsigned long long start_pfn_64; /* header_version 6 and later */ + unsigned long long end_pfn_64; /* header_version 6 and later */ + unsigned long long max_mapnr_64; /* header_version 6 and later */ + }; + + - 1st-bitmap + The bit of 1st-bitmap presents either a page on memory hole, or not. + If a page is on memory hole, the corresponding bit is off. Otherwise, + it is on. + + + - 2nd-bitmap + The bit of 2nd-bitmap presents either a dumpable page, or not. + If a page is on memory hole or excluded by makedumpfile command, the + corresponding bit is off. Otherwise, it is on. + + + - page header + There are page headers corresponding to dumpable pages. + This header presents the corresponding page information (compressed, or not. + etc.) + + typedef struct page_desc { + off_t offset; /* the offset of the page data*/ + unsigned int size; /* the size of this dump page */ + unsigned int flags; /* flags */ + unsigned long long page_flags; /* page flags */ + } page_desc_t; + + +* The ELF format + There are two different ELF format(ELF32, ELF64) for K-bit architectures (K=32,64). + Since they almost have the same behaviour in this situation, the following will use + ELF32 as a example. + + - The file structure + + +---------------------------------+ + | elf_header (struct elf32_hdr) | + |---------------------------------+ + | PT_NOTE (struct elf32_phdr) | + |---------------------------------+ + | PT_LOAD(1) (struct elf32_phdr) | + | PT_LOAD(2) (struct elf32_phdr) | + | : | + | PT_LOAD(Z) (struct elf32_phdr) | + |---------------------------------+ + | NOTE | + |---------------------------------+ + | segment(1) | + | segment(2) | + | : | + | segment(Z) | + +---------------------------------+ + + - elf_header + This header is almost the same as a normal elf_header. The difference is that the + e_flags is used for indicating whether the dump file is complete or not. + 0x0 : complete, + 0x1 : incomplete + + typedef struct elf32_hdr{ + unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ + Elf32_Half e_type; /* Object file type (CORE) */ + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; /* Size of this header */ + Elf32_Half e_phentsize; /* Size of program headers */ + Elf32_Half e_phnum; /* Number of program headers */ + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; + } Elf32_Ehdr; + + - PT_NOTE and PT_LOAD + PT_NOTE corresponds to NOTE and PT_LOAD to segment. + They present the corresponding NOTE and segments information. + + + typedef struct elf32_phdr{ + Elf32_Word p_type; + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; + Elf32_Word p_align; /* Segment alignment, file & memory */ + } Elf32_Phdr; + + - note + The note structure + + +------------------------------------+ + | note header 1 (struct elf32_note) | + | note header 2 (struct elf32_note) | + | : | + | note header N (struct elf32_note) | + |------------------------------------+ + | note data 1 | + | note data 2 | + | : | + | note data N | + +------------------------------------+ + + typedef struct elf32_note { + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ + } Elf32_Nhdr; + + - segments + The data dumped are all stored in segments and notes. + + +* The incomplete DUMPFILE + When generating DUMPFILE, if ENOSPACE error happens, the DUMPFILE will be + incomplete. + + - The incomplete kdump-compressed DUMPFILE + + the complete the incomplete + +-----------------------+ +-----------------------+ + | main header | | main header | have incomplete flag + |-----------------------+ |-----------------------+ + | sub header | | sub header | + |-----------------------+ |-----------------------+ + | 1st-bitmap | | 1st-bitmap | + |-----------------------+ |-----------------------+ + | 2nd-bitmap | | 2nd-bitmap | + |-----------------------+ |-----------------------+ + | page header for pfn 0 | | page header for pfn 0 | + | page header for pfn 1 | | page header for pfn 1 | + | : | | : | + | page header for pfn N | | page header for pfn N | The page headers after + | : | | | N don't exist. The + | page header for pfn Z | | | value of it is zero, + |-----------------------| |-----------------------| when try to read it. + | page data (pfn 0) | | page data (pfn 0) | + | page data (pfn 1) | | page data (pfn 1) | + | : | | : | + | page data (pfn N) | | page data (pfn N) | + | : | +-----------------------+ + | page data (pfn Z) | + +-----------------------+ + + The incomplete flag is set into status of disk_dump_header by + status |= DUMP_DH_COMPRESSED_INCOMPLETE + DUMP_DH_COMPRESSED_INCOMPLETE : 0x8 + + The page header and page data are written in pairs. When writing page data + (pfn N+1), if ENOSPACE error happens, the page headers after N won't be + written either. + Since the data lost is filled with zero when it is read, the page_desc->offset + will also be zero. And zero page has its own offset not equal 0. So when reading + page from incomplete core, only the page lost by ENOSPACE errors has 0 in its + corresponding page descriptor's member offset. + + If there is no page data dumped into the DUMPFILE, the DUMPFILE can't be + analysed by crash. + + - The incomplete elf DUMPFILE + + the complete the incomplete + +-------------+ +-------------+ + | elf header | | elf header | have incomplete flag + |-------------+ |-------------+ + | PT_NOTE | | PT_NOTE | + | PT_LOAD(1) | | PT_LOAD(1) | + | : | | : | + | PT_LOAD(N) | | PT_LOAD(N) | The PT_LOAD after N don't exist. + | : | | | The value of it is zero, when try + | PT_LOAD(Z) | | | to read it. + |-------------+ |-------------+ + | NOTE | | NOTE | + |-------------+ |-------------+ + | segment(1) | | segment(1) | + | : | | : | + | segment(N) | | segment(N) | The segment(N) is incomplete. + | : | +-------------+ The segments after N don't exist. + | segment(Z) | + +-------------+ + + The incomplete flag is set into e_flags of elf_header by + e_flags |= DUMP_ELF_INCOMPLETE + DUMP_ELF_INCOMPLETE : 0x1 + + The PT_LOAD and segment are written in pairs. When writing segment(N) + , if ENOSPACE error happens, the PT_LOAD after N won't be written + either. + + If there is no segment dumped into the DUMPFILE, the DUMPFILE can't be + analysed by crash. |