Set page_size, nr_cpus and time stamp. Also, initialize bitmap table in the same way as initialize_bitmap_memory() for kdump-compressed format. Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com> --- makedumpfile.c | 28 +++++++++++ sadump_info.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sadump_info.h | 36 ++++++++++++++ sadump_mod.h | 2 + 4 files changed, 210 insertions(+), 0 deletions(-) diff --git a/makedumpfile.c b/makedumpfile.c index 96faf60..1686dff 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -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", + sadump_format_type_name(), info->name_memory); + 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; diff --git a/sadump_info.c b/sadump_info.c index 2f66148..6b2b7bc 100644 --- a/sadump_info.c +++ b/sadump_info.c @@ -39,6 +39,7 @@ struct sadump_info { unsigned long sub_hdr_offset; uint32_t smram_cpu_state_size; unsigned long data_offset; + unsigned long *block_table; }; static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen); @@ -505,6 +506,125 @@ error: } int +sadump_initialize_bitmap_memory(void) +{ + struct sadump_header *sh = si->sh_memory; + struct dump_bitmap *bmp; + unsigned long dumpable_bitmap_offset, dumpable_bitmap_len; + unsigned long section, max_section, pfn; + unsigned long *block_table; + + dumpable_bitmap_offset = + si->sub_hdr_offset + + sh->block_size * (sh->sub_hdr_size + sh->bitmap_blocks); + + dumpable_bitmap_len = sh->block_size * sh->dumpable_bitmap_blocks; + + bmp = malloc(sizeof(struct dump_bitmap)); + if (bmp == NULL) { + ERRMSG("Can't allocate memory for the memory-bitmap. %s\n", + strerror(errno)); + return FALSE; + } + bmp->fd = info->fd_memory; + bmp->file_name = info->name_memory; + bmp->no_block = -1; + memset(bmp->buf, 0, BUFSIZE_BITMAP); + bmp->offset = dumpable_bitmap_offset; + + max_section = divideup(sh->max_mapnr, SADUMP_PF_SECTION_NUM); + + block_table = calloc(sizeof(unsigned long), max_section); + if (block_table == NULL) { + ERRMSG("Can't allocate memory for the block_table. %s\n", + strerror(errno)); + free(bmp); + return FALSE; + } + + for (section = 0; section < max_section; ++section) { + if (section > 0) + block_table[section] = block_table[section-1]; + for (pfn = section * SADUMP_PF_SECTION_NUM; + pfn < (section + 1) * SADUMP_PF_SECTION_NUM; + ++pfn) + if (is_dumpable(bmp, pfn)) + block_table[section]++; + } + + info->bitmap_memory = bmp; + si->block_table = block_table; + + return TRUE; +} + +int +sadump_get_nr_cpus(int *nr_cpus) +{ + unsigned long offset; + struct sadump_smram_cpu_state scs, zero; + uint32_t x_cpu; + int count; + + memset(&zero, 0, sizeof(zero)); + + offset = si->sub_hdr_offset + sizeof(uint32_t) + + si->sh_memory->nr_cpus * sizeof(struct sadump_apic_state); + + count = 0; + for (x_cpu = 0; x_cpu < si->sh_memory->nr_cpus; ++x_cpu) { + if (!read_device(&scs, sizeof(scs), &offset)) + return FALSE; + if (memcmp(&scs, &zero, sizeof(scs)) != 0) + count++; + } + + *nr_cpus = count; + + DEBUG_MSG("sadump: nr_cpus: %d\n", *nr_cpus); + + return TRUE; +} + +int +sadump_set_timestamp(struct timeval *ts) +{ + static struct tm t; + efi_time_t *e = &si->sph_memory->time_stamp; + time_t ti; + + memset(&t, 0, sizeof(t)); + + t.tm_sec = e->second; + t.tm_min = e->minute; + t.tm_hour = e->hour; + t.tm_mday = e->day; + t.tm_mon = e->month - 1; + t.tm_year = e->year - 1900; + + if (e->timezone != EFI_UNSPECIFIED_TIMEZONE) + t.tm_hour += e->timezone; + + else + DEBUG_MSG("sadump: timezone information is missing\n"); + + ti = mktime(&t); + if (ti == (time_t)-1) + return FALSE; + + ts->tv_sec = ti; + ts->tv_usec = 0; + + return TRUE; +} + +unsigned long long +sadump_get_max_mapnr(void) +{ + return si->sh_memory->max_mapnr; +} + +int sadump_add_diskset_info(char *name_memory) { si->num_disks++; @@ -523,12 +643,34 @@ sadump_add_diskset_info(char *name_memory) return TRUE; } +long +sadump_page_size(void) +{ + return si->sh_memory->block_size; +} + char * sadump_head_disk_name_memory(void) { return si->diskset_info[0].name_memory; } +char * +sadump_format_type_name(void) +{ + switch (info->flag_sadump) { + case SADUMP_SINGLE_PARTITION: + return "single partition"; + case SADUMP_DISKSET: + return "diskset"; + case SADUMP_MEDIA_BACKUP: + return "media backup"; + case SADUMP_UNKNOWN: + return "unknown"; + } + return NULL; +} + void free_sadump_info(void) { @@ -551,6 +693,8 @@ free_sadump_info(void) } free(si->diskset_info); } + if (si->block_table) + free(si->block_table); } #endif /* defined(__x86__) && defined(__x86_64__) */ diff --git a/sadump_info.h b/sadump_info.h index c54d29f..0a04141 100644 --- a/sadump_info.h +++ b/sadump_info.h @@ -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; diff --git a/sadump_mod.h b/sadump_mod.h index 3385123..efd059f 100644 --- a/sadump_mod.h +++ b/sadump_mod.h @@ -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__) */ /* -- 1.7.4.4