[PATCH v2 06/14] Initialize internal data according to sadump-related formats

HATAYAMA Daisuke
2011-10-28T09:48:41Z

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@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..c5ea9ce 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",
+ 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;

diff --git a/sadump_info.c b/sadump_info.c
index 2f66148..2efeb63 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 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 long section, max_section, pfn;
+ unsigned long 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 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__) */

/*