| 1 | /* |
| 2 | * QEMU dump |
| 3 | * |
| 4 | * Copyright Fujitsu, Corp. 2011, 2012 |
| 5 | * |
| 6 | * Authors: |
| 7 | * Wen Congyang <wency@cn.fujitsu.com> |
| 8 | * |
| 9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 10 | * See the COPYING file in the top-level directory. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | #ifndef DUMP_H |
| 15 | #define DUMP_H |
| 16 | |
| 17 | #include "qapi/qapi-types-dump.h" |
| 18 | #include "qemu/thread.h" |
| 19 | |
| 20 | #define MAKEDUMPFILE_SIGNATURE "makedumpfile" |
| 21 | #define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */ |
| 22 | #define TYPE_FLAT_HEADER (1) /* type of flattened format */ |
| 23 | #define VERSION_FLAT_HEADER (1) /* version of flattened format */ |
| 24 | #define END_FLAG_FLAT_HEADER (-1) |
| 25 | |
| 26 | #ifndef ARCH_PFN_OFFSET |
| 27 | #define ARCH_PFN_OFFSET (0) |
| 28 | #endif |
| 29 | |
| 30 | /* |
| 31 | * flag for compressed format |
| 32 | */ |
| 33 | #define DUMP_DH_COMPRESSED_ZLIB (0x1) |
| 34 | #define DUMP_DH_COMPRESSED_LZO (0x2) |
| 35 | #define DUMP_DH_COMPRESSED_SNAPPY (0x4) |
| 36 | |
| 37 | #define KDUMP_SIGNATURE "KDUMP " |
| 38 | #define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1) |
| 39 | #define DUMP_LEVEL (1) |
| 40 | #define DISKDUMP_HEADER_BLOCKS (1) |
| 41 | |
| 42 | #include "system/dump-arch.h" |
| 43 | #include "system/memory_mapping.h" |
| 44 | |
| 45 | typedef struct QEMU_PACKED MakedumpfileHeader { |
| 46 | char signature[16]; /* = "makedumpfile" */ |
| 47 | int64_t type; |
| 48 | int64_t version; |
| 49 | } MakedumpfileHeader; |
| 50 | |
| 51 | typedef struct QEMU_PACKED MakedumpfileDataHeader { |
| 52 | int64_t offset; |
| 53 | int64_t buf_size; |
| 54 | } MakedumpfileDataHeader; |
| 55 | |
| 56 | typedef struct QEMU_PACKED NewUtsname { |
| 57 | char sysname[65]; |
| 58 | char nodename[65]; |
| 59 | char release[65]; |
| 60 | char version[65]; |
| 61 | char machine[65]; |
| 62 | char domainname[65]; |
| 63 | } NewUtsname; |
| 64 | |
| 65 | typedef struct QEMU_PACKED DiskDumpHeader32 { |
| 66 | char signature[SIG_LEN]; /* = "KDUMP " */ |
| 67 | uint32_t header_version; /* Dump header version */ |
| 68 | NewUtsname utsname; /* copy of system_utsname */ |
| 69 | char timestamp[10]; /* Time stamp */ |
| 70 | uint32_t status; /* Above flags */ |
| 71 | uint32_t block_size; /* Size of a block in byte */ |
| 72 | uint32_t sub_hdr_size; /* Size of arch dependent header in block */ |
| 73 | uint32_t bitmap_blocks; /* Size of Memory bitmap in block */ |
| 74 | uint32_t max_mapnr; /* = max_mapnr , |
| 75 | obsoleted in header_version 6 */ |
| 76 | uint32_t total_ram_blocks; /* Number of blocks should be written */ |
| 77 | uint32_t device_blocks; /* Number of total blocks in dump device */ |
| 78 | uint32_t written_blocks; /* Number of written blocks */ |
| 79 | uint32_t current_cpu; /* CPU# which handles dump */ |
| 80 | uint32_t nr_cpus; /* Number of CPUs */ |
| 81 | } DiskDumpHeader32; |
| 82 | |
| 83 | typedef struct QEMU_PACKED DiskDumpHeader64 { |
| 84 | char signature[SIG_LEN]; /* = "KDUMP " */ |
| 85 | uint32_t header_version; /* Dump header version */ |
| 86 | NewUtsname utsname; /* copy of system_utsname */ |
| 87 | char timestamp[22]; /* Time stamp */ |
| 88 | uint32_t status; /* Above flags */ |
| 89 | uint32_t block_size; /* Size of a block in byte */ |
| 90 | uint32_t sub_hdr_size; /* Size of arch dependent header in block */ |
| 91 | uint32_t bitmap_blocks; /* Size of Memory bitmap in block */ |
| 92 | uint32_t max_mapnr; /* = max_mapnr, |
| 93 | obsoleted in header_version 6 */ |
| 94 | uint32_t total_ram_blocks; /* Number of blocks should be written */ |
| 95 | uint32_t device_blocks; /* Number of total blocks in dump device */ |
| 96 | uint32_t written_blocks; /* Number of written blocks */ |
| 97 | uint32_t current_cpu; /* CPU# which handles dump */ |
| 98 | uint32_t nr_cpus; /* Number of CPUs */ |
| 99 | } DiskDumpHeader64; |
| 100 | |
| 101 | typedef struct QEMU_PACKED KdumpSubHeader32 { |
| 102 | uint32_t phys_base; |
| 103 | uint32_t dump_level; /* header_version 1 and later */ |
| 104 | uint32_t split; /* header_version 2 and later */ |
| 105 | uint32_t start_pfn; /* header_version 2 and later, |
| 106 | obsoleted in header_version 6 */ |
| 107 | uint32_t end_pfn; /* header_version 2 and later, |
| 108 | obsoleted in header_version 6 */ |
| 109 | uint64_t offset_vmcoreinfo; /* header_version 3 and later */ |
| 110 | uint32_t size_vmcoreinfo; /* header_version 3 and later */ |
| 111 | uint64_t offset_note; /* header_version 4 and later */ |
| 112 | uint32_t note_size; /* header_version 4 and later */ |
| 113 | uint64_t offset_eraseinfo; /* header_version 5 and later */ |
| 114 | uint32_t size_eraseinfo; /* header_version 5 and later */ |
| 115 | uint64_t start_pfn_64; /* header_version 6 and later */ |
| 116 | uint64_t end_pfn_64; /* header_version 6 and later */ |
| 117 | uint64_t max_mapnr_64; /* header_version 6 and later */ |
| 118 | } KdumpSubHeader32; |
| 119 | |
| 120 | typedef struct QEMU_PACKED KdumpSubHeader64 { |
| 121 | uint64_t phys_base; |
| 122 | uint32_t dump_level; /* header_version 1 and later */ |
| 123 | uint32_t split; /* header_version 2 and later */ |
| 124 | uint64_t start_pfn; /* header_version 2 and later, |
| 125 | obsoleted in header_version 6 */ |
| 126 | uint64_t end_pfn; /* header_version 2 and later, |
| 127 | obsoleted in header_version 6 */ |
| 128 | uint64_t offset_vmcoreinfo; /* header_version 3 and later */ |
| 129 | uint64_t size_vmcoreinfo; /* header_version 3 and later */ |
| 130 | uint64_t offset_note; /* header_version 4 and later */ |
| 131 | uint64_t note_size; /* header_version 4 and later */ |
| 132 | uint64_t offset_eraseinfo; /* header_version 5 and later */ |
| 133 | uint64_t size_eraseinfo; /* header_version 5 and later */ |
| 134 | uint64_t start_pfn_64; /* header_version 6 and later */ |
| 135 | uint64_t end_pfn_64; /* header_version 6 and later */ |
| 136 | uint64_t max_mapnr_64; /* header_version 6 and later */ |
| 137 | } KdumpSubHeader64; |
| 138 | |
| 139 | typedef struct DataCache { |
| 140 | DumpState *state; /* dump state related to this data */ |
| 141 | uint8_t *buf; /* buffer for cached data */ |
| 142 | size_t buf_size; /* size of the buf */ |
| 143 | size_t data_size; /* size of cached data in buf */ |
| 144 | off_t offset; /* offset of the file */ |
| 145 | } DataCache; |
| 146 | |
| 147 | typedef struct QEMU_PACKED PageDescriptor { |
| 148 | uint64_t offset; /* the offset of the page data*/ |
| 149 | uint32_t size; /* the size of this dump page */ |
| 150 | uint32_t flags; /* flags */ |
| 151 | uint64_t page_flags; /* page flags */ |
| 152 | } PageDescriptor; |
| 153 | |
| 154 | typedef struct DumpState { |
| 155 | GuestPhysBlockList guest_phys_blocks; |
| 156 | ArchDumpInfo dump_info; |
| 157 | MemoryMappingList list; |
| 158 | bool resume; |
| 159 | bool detached; |
| 160 | bool kdump_raw; |
| 161 | hwaddr memory_offset; |
| 162 | int fd; |
| 163 | |
| 164 | /* |
| 165 | * Dump filter area variables |
| 166 | * |
| 167 | * A filtered dump only contains the guest memory designated by |
| 168 | * the start address and length variables defined below. |
| 169 | * |
| 170 | * If length is 0, no filtering is applied. |
| 171 | */ |
| 172 | int64_t filter_area_begin; /* Start address of partial guest memory area */ |
| 173 | int64_t filter_area_length; /* Length of partial guest memory area */ |
| 174 | |
| 175 | /* Elf dump related data */ |
| 176 | uint32_t phdr_num; |
| 177 | uint32_t shdr_num; |
| 178 | ssize_t note_size; |
| 179 | hwaddr shdr_offset; |
| 180 | hwaddr phdr_offset; |
| 181 | hwaddr section_offset; |
| 182 | hwaddr note_offset; |
| 183 | |
| 184 | void *elf_section_hdrs; /* Pointer to section header buffer */ |
| 185 | void *elf_section_data; /* Pointer to section data buffer */ |
| 186 | uint64_t elf_section_data_size; /* Size of section data */ |
| 187 | GArray *string_table_buf; /* String table data buffer */ |
| 188 | |
| 189 | uint8_t *note_buf; /* buffer for notes */ |
| 190 | size_t note_buf_offset; /* the writing place in note_buf */ |
| 191 | uint32_t nr_cpus; /* number of guest's cpu */ |
| 192 | uint64_t max_mapnr; /* the biggest guest's phys-mem's number */ |
| 193 | size_t len_dump_bitmap; /* the size of the place used to store |
| 194 | dump_bitmap in vmcore */ |
| 195 | off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */ |
| 196 | off_t offset_page; /* offset of page part in vmcore */ |
| 197 | size_t num_dumpable; /* number of page that can be dumped */ |
| 198 | uint32_t flag_compress; /* indicate the compression format */ |
| 199 | DumpStatus status; /* current dump status */ |
| 200 | |
| 201 | bool has_format; /* whether format is provided */ |
| 202 | DumpGuestMemoryFormat format; /* valid only if has_format == true */ |
| 203 | QemuThread dump_thread; /* thread for detached dump */ |
| 204 | |
| 205 | int64_t total_size; /* total memory size (in bytes) to |
| 206 | * be dumped. When filter is |
| 207 | * enabled, this will only count |
| 208 | * those to be written. */ |
| 209 | int64_t written_size; /* written memory size (in bytes), |
| 210 | * this could be used to calculate |
| 211 | * how much work we have |
| 212 | * finished. */ |
| 213 | uint8_t *guest_note; /* ELF note content */ |
| 214 | size_t guest_note_size; |
| 215 | } DumpState; |
| 216 | |
| 217 | uint16_t cpu_to_dump16(DumpState *s, uint16_t val); |
| 218 | uint32_t cpu_to_dump32(DumpState *s, uint32_t val); |
| 219 | uint64_t cpu_to_dump64(DumpState *s, uint64_t val); |
| 220 | |
| 221 | int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start, |
| 222 | int64_t filter_area_length); |
| 223 | int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start, |
| 224 | int64_t filter_area_length); |
| 225 | #endif |