>When --split is specified in cyclic mode, start_pfn and end_pfn of each dumpfile >will be calculated to make each dumpfile have the same size. > >Signed-off-by: Qiao Nuohan <qiaonuohan at cn.fujitsu.com> >Signed-off-by: Zhou Wenjian <zhouwj-fnst at cn.fujitsu.com> >--- > makedumpfile.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 66 insertions(+), 5 deletions(-) > >diff --git a/makedumpfile.c b/makedumpfile.c >index a01c616..831e7de 100644 >--- a/makedumpfile.c >+++ b/makedumpfile.c >@@ -8217,6 +8217,63 @@ out: > return ret; > } > >+/* >+ * calculate end_pfn of one dumpfile. >+ * try to make every output file have the same size. >+ * splitblock_table is used to reduce calculate time. >+ */ >+ >+#define CURRENT_SPLITBLOCK_PFN_NUM (*cur_splitblock_num * splitblock->page_per_splitblock) >+mdf_pfn_t >+calculate_end_pfn_by_splitblock(mdf_pfn_t start_pfn, >+ int *cur_splitblock_num) >+{ >+ if (start_pfn >= info->max_mapnr) >+ return info->max_mapnr; >+ >+ mdf_pfn_t end_pfn; >+ long long pfn_needed, offset; >+ char *splitblock_value_offset; >+ >+ pfn_needed = info->num_dumpable / info->num_dumpfile; pfn_needed is calculated by rounding-down, so... >+ offset = *cur_splitblock_num * splitblock->entry_size; >+ splitblock_value_offset = splitblock->table + offset; >+ end_pfn = start_pfn; >+ >+ while (*cur_splitblock_num < splitblock->num && pfn_needed > 0) { >+ pfn_needed -= read_from_splitblock_table(splitblock_value_offset); >+ splitblock_value_offset += splitblock->entry_size; >+ ++*cur_splitblock_num; >+ } >+ >+ end_pfn = CURRENT_SPLITBLOCK_PFN_NUM; >+ if (end_pfn > info->max_mapnr) >+ end_pfn = info->max_mapnr; >+ >+ return end_pfn; >+} >+ >+/* >+ * calculate start_pfn and end_pfn in each output file. >+ */ >+static int setup_splitting_cyclic(void) >+{ >+ int i; >+ mdf_pfn_t start_pfn, end_pfn; >+ int cur_splitblock_num = 0; >+ start_pfn = end_pfn = 0; >+ >+ for (i = 0; i < info->num_dumpfile; i++) { >+ start_pfn = end_pfn; >+ end_pfn = calculate_end_pfn_by_splitblock(start_pfn, >+ &cur_splitblock_num); >+ SPLITTING_START_PFN(i) = start_pfn; >+ SPLITTING_END_PFN(i) = end_pfn; >+ } the last SPLITTING_END_PFN can be shorter than the max_mapnr like: kdump sub header phys_base : 0x0 dump_level : 30 split : 1 start_pfn : 0x11b609 end_pfn : 0x11fffe start_pfn_64 : 0x11b609 end_pfn_64 : 0x11fffe /* shorter than max_mapnr */ max_mapnr_64 : 0x120000 offset_vmcoreinfo: 0x1610 size_vmcoreinfo : 0x1726 ... then reassembling will fail like below: $ ./makedumpfile --reassemble split1 split2 split3 dumpfile check_splitting_info: There is not dumpfile corresponding to pfn 0x11fffe - 0x120000. makedumpfile Failed. $ We should adjust the last SPLITTING_END_PFN to max_mapnr. Thanks, Atsushi Kumagai >+ >+ return TRUE; >+} >+ > int > setup_splitting(void) > { >@@ -8230,12 +8287,16 @@ setup_splitting(void) > return FALSE; > > if (info->flag_cyclic) { >- for (i = 0; i < info->num_dumpfile; i++) { >- SPLITTING_START_PFN(i) = divideup(info->max_mapnr, info->num_dumpfile) * i; >- SPLITTING_END_PFN(i) = divideup(info->max_mapnr, info->num_dumpfile) * (i + 1); >+ int ret = FALSE; >+ >+ if(!prepare_bitmap2_buffer_cyclic()){ >+ free_bitmap_buffer(); >+ return ret; > } >- if (SPLITTING_END_PFN(i-1) > info->max_mapnr) >- SPLITTING_END_PFN(i-1) = info->max_mapnr; >+ ret = setup_splitting_cyclic(); >+ free_bitmap2_buffer_cyclic(); >+ >+ return ret; > } else { > initialize_2nd_bitmap(&bitmap2); > >-- >1.7.1 > > >_______________________________________________ >kexec mailing list >kexec at lists.infradead.org >http://lists.infradead.org/mailman/listinfo/kexec