summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--README2
-rw-r--r--arch/arm64.c75
-rw-r--r--arch/ppc64.c5
-rw-r--r--arch/x86_64.c22
-rw-r--r--dwarf_info.c3
-rw-r--r--elf_info.c7
-rw-r--r--makedumpfile.82
-rw-r--r--makedumpfile.c132
-rw-r--r--makedumpfile.conf.52
-rw-r--r--makedumpfile.h23
-rw-r--r--makedumpfile.spec4
-rw-r--r--print_info.c32
-rw-r--r--print_info.h6
-rw-r--r--sadump_info.c4
15 files changed, 244 insertions, 91 deletions
diff --git a/Makefile b/Makefile
index 612b9d0..ea3c47d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# makedumpfile
-VERSION=1.6.4
-DATE=3 Jul 2018
+VERSION=1.6.5
+DATE=5 Dec 2018
# Honour the environment variable CC
ifeq ($(strip $CC),)
@@ -68,6 +68,18 @@ endif
LIBS := -lpthread $(LIBS)
+try-run = $(shell set -e; \
+ TMP=".$$$$.tmp"; \
+ if ($(1)) >/dev/null 2>&1; \
+ then echo "$(2)"; \
+ else echo "$(3)"; \
+ fi; \
+ rm -f "$$TMP")
+
+LINK_TEST_PROG="int clock_gettime(); int main(){ return clock_gettime(); }"
+LIBS := $(LIBS) $(call try-run,\
+ echo $(LINK_TEST_PROG) | $(CC) $(CFLAGS) -o "$$TMP" -x c -,,-lrt)
+
all: makedumpfile
$(OBJ_PART): $(SRC_PART)
diff --git a/README b/README
index 583179e..628c60f 100644
--- a/README
+++ b/README
@@ -125,6 +125,8 @@
4.15 | OK | ** | | | | ** | | -- | OK | OK | | |
4.16 | OK | ** | | | | ** | | -- | OK | OK | | |
4.17 | OK | ** | | | | ** | | -- | OK | OK | | |
+ 4.18 | OK | ** | | | | ** | | -- | OK | OK | | |
+ 4.19 | OK | ** | | | | ** | | -- | OK | OK | | |
OK : Support.
-- : Not support.
diff --git a/arch/arm64.c b/arch/arm64.c
index 2fd3e18..0535193 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -174,11 +174,76 @@ get_kvbase_arm64(void)
int
get_phys_base_arm64(void)
{
- info->phys_base = NUMBER(PHYS_OFFSET);
+ int i;
+ unsigned long long phys_start;
+ unsigned long long virt_start;
+
+ if (NUMBER(PHYS_OFFSET) != NOT_FOUND_NUMBER) {
+ info->phys_base = NUMBER(PHYS_OFFSET);
+ DEBUG_MSG("phys_base : %lx (vmcoreinfo)\n",
+ info->phys_base);
+ return TRUE;
+ }
- DEBUG_MSG("phys_base : %lx\n", info->phys_base);
+ if (get_num_pt_loads() && PAGE_OFFSET) {
+ for (i = 0;
+ get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
+ i++) {
+ if (virt_start != NOT_KV_ADDR
+ && virt_start >= PAGE_OFFSET
+ && phys_start != NOT_PADDR) {
+ info->phys_base = phys_start -
+ (virt_start & ~PAGE_OFFSET);
+ DEBUG_MSG("phys_base : %lx (pt_load)\n",
+ info->phys_base);
+ return TRUE;
+ }
+ }
+ }
- return TRUE;
+ ERRMSG("Cannot determine phys_base\n");
+ return FALSE;
+}
+
+unsigned long
+get_kaslr_offset_arm64(unsigned long vaddr)
+{
+ unsigned int i;
+ char buf[BUFSIZE_FGETS], *endp;
+
+ if (!info->kaslr_offset && info->file_vmcoreinfo) {
+ if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
+ ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
+ info->name_vmcoreinfo, strerror(errno));
+ return FALSE;
+ }
+
+ while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
+ i = strlen(buf);
+ if (!i)
+ break;
+ if (buf[i - 1] == '\n')
+ buf[i - 1] = '\0';
+ if (strncmp(buf, STR_KERNELOFFSET,
+ strlen(STR_KERNELOFFSET)) == 0) {
+ info->kaslr_offset =
+ strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16);
+ DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset);
+ }
+ }
+ }
+
+ if (vaddr >= __START_KERNEL_map &&
+ vaddr < __START_KERNEL_map + info->kaslr_offset) {
+ DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset);
+ return info->kaslr_offset;
+ } else {
+ /*
+ * TODO: we need to check if it is vmalloc/vmmemmap/module
+ * address, we will have different offset
+ */
+ return 0;
+ }
}
ulong
@@ -291,8 +356,8 @@ get_versiondep_info_arm64(void)
info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
- DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset,
- va_bits);
+ DEBUG_MSG("va_bits : %d\n", va_bits);
+ DEBUG_MSG("page_offset : %lx\n", info->page_offset);
return TRUE;
}
diff --git a/arch/ppc64.c b/arch/ppc64.c
index 8b6f7d5..947a125 100644
--- a/arch/ppc64.c
+++ b/arch/ppc64.c
@@ -481,6 +481,11 @@ set_ppc64_max_physmem_bits(void)
|| (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT())))
return TRUE;
+ info->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
+ if ((array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME()))
+ || (array_len == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT())))
+ return TRUE;
+
return FALSE;
}
diff --git a/arch/x86_64.c b/arch/x86_64.c
index 2b3c0bb..537fb78 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -86,8 +86,9 @@ get_page_offset_x86_64(void)
unsigned long long phys_start;
unsigned long long virt_start;
unsigned long page_offset_base;
+ unsigned long page_offset = 0;
- if (info->kaslr_offset && (info->fd_vmlinux != -1)) {
+ if (info->kaslr_offset && info->name_vmlinux) {
page_offset_base = get_symbol_addr("page_offset_base");
page_offset_base += info->kaslr_offset;
if (!readmem(VADDR, page_offset_base, &info->page_offset,
@@ -95,20 +96,32 @@ get_page_offset_x86_64(void)
ERRMSG("Can't read page_offset_base.\n");
return FALSE;
}
+ DEBUG_MSG("page_offset : %lx (vmlinux page_offset_base)\n",
+ info->page_offset);
return TRUE;
}
if (get_num_pt_loads()) {
+ /*
+ * Linux 4.19 (only) adds KCORE_REMAP PT_LOADs, which have
+ * virt_start < __START_KERNEL_map, to /proc/kcore. In order
+ * not to select them, we select the last valid PT_LOAD.
+ */
for (i = 0;
get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
i++) {
if (virt_start != NOT_KV_ADDR
&& virt_start < __START_KERNEL_map
&& phys_start != NOT_PADDR) {
- info->page_offset = virt_start - phys_start;
- return TRUE;
+ page_offset = virt_start - phys_start;
}
}
+ if (page_offset) {
+ info->page_offset = page_offset;
+ DEBUG_MSG("page_offset : %lx (pt_load)\n",
+ info->page_offset);
+ return TRUE;
+ }
}
if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
@@ -119,6 +132,7 @@ get_page_offset_x86_64(void)
info->page_offset = __PAGE_OFFSET_2_6_27;
}
+ DEBUG_MSG("page_offset : %lx (constant)\n", info->page_offset);
return TRUE;
}
@@ -139,7 +153,7 @@ get_phys_base_x86_64(void)
}
/* linux-2.6.21 or older don't have phys_base, should be set to 0. */
- if (!has_vmcoreinfo()) {
+ if (!has_vmcoreinfo() && info->name_vmlinux) {
SYMBOL_INIT(phys_base, "phys_base");
if (SYMBOL(phys_base) == NOT_FOUND_SYMBOL) {
return TRUE;
diff --git a/dwarf_info.c b/dwarf_info.c
index 4f9ad12..e42a9f5 100644
--- a/dwarf_info.c
+++ b/dwarf_info.c
@@ -752,7 +752,8 @@ search_typedef(Dwarf_Die *die, int *found)
continue;
*found = TRUE;
- strncpy(dwarf_info.src_name, src_name, LEN_SRCFILE);
+ strncpy(dwarf_info.src_name, src_name, LEN_SRCFILE-1);
+ dwarf_info.src_name[LEN_SRCFILE-1] = '\0';
break;
}
} while (!dwarf_siblingof(die, die));
diff --git a/elf_info.c b/elf_info.c
index 711601a..1d33e96 100644
--- a/elf_info.c
+++ b/elf_info.c
@@ -372,7 +372,7 @@ int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len)
off_t offset_desc;
offset = UNINITIALIZED;
- kvaddr = (ulong)vmcoreinfo_addr + PAGE_OFFSET;
+ kvaddr = paddr_to_vaddr(vmcoreinfo_addr);
for (i = 0; i < num_pt_loads; ++i) {
struct pt_load_segment *p = &pt_loads[i];
@@ -810,10 +810,11 @@ static int exclude_segment(struct pt_load_segment **pt_loads,
int i, j, tidx = -1;
unsigned long long vstart, vend, kvstart, kvend;
struct pt_load_segment temp_seg = {0};
- kvstart = (ulong)start + PAGE_OFFSET;
- kvend = (ulong)end + PAGE_OFFSET;
unsigned long size;
+ kvstart = paddr_to_vaddr(start);
+ kvend = paddr_to_vaddr(end);
+
for (i = 0; i < (*num_pt_loads); i++) {
vstart = (*pt_loads)[i].virt_start;
vend = (*pt_loads)[i].virt_end;
diff --git a/makedumpfile.8 b/makedumpfile.8
index 8482134..5294026 100644
--- a/makedumpfile.8
+++ b/makedumpfile.8
@@ -1,4 +1,4 @@
-.TH MAKEDUMPFILE 8 "3 Jul 2018" "makedumpfile v1.6.4" "Linux System Administrator's Manual"
+.TH MAKEDUMPFILE 8 "5 Dec 2018" "makedumpfile v1.6.5" "Linux System Administrator's Manual"
.SH NAME
makedumpfile \- make a small dumpfile of kdump
.SH SYNOPSIS
diff --git a/makedumpfile.c b/makedumpfile.c
index 1ed3d61..8923538 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2084,7 +2084,7 @@ is_sparsemem_extreme(void)
{
if ((ARRAY_LENGTH(mem_section)
== divideup(NR_MEM_SECTIONS(), _SECTIONS_PER_ROOT_EXTREME()))
- || (ARRAY_LENGTH(mem_section) == NOT_FOUND_SYMBOL))
+ || (ARRAY_LENGTH(mem_section) == NOT_FOUND_STRUCTURE))
return TRUE;
else
return FALSE;
@@ -5364,7 +5364,7 @@ _exclude_free_page(struct cycle *cycle)
{
int i, nr_zones, num_nodes, node;
unsigned long node_zones, zone, spanned_pages, pgdat;
- struct timeval tv_start;
+ struct timespec ts_start;
if ((node = next_online_node(0)) < 0) {
ERRMSG("Can't get next online node.\n");
@@ -5374,7 +5374,7 @@ _exclude_free_page(struct cycle *cycle)
ERRMSG("Can't get pgdat list.\n");
return FALSE;
}
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
for (num_nodes = 1; num_nodes <= vt.numnodes; num_nodes++) {
@@ -5420,7 +5420,7 @@ _exclude_free_page(struct cycle *cycle)
* print [100 %]
*/
print_progress(PROGRESS_FREE_PAGES, vt.numnodes, vt.numnodes, NULL);
- print_execution_time(PROGRESS_FREE_PAGES, &tv_start);
+ print_execution_time(PROGRESS_FREE_PAGES, &ts_start);
return TRUE;
}
@@ -5516,6 +5516,27 @@ out:
"follow free lists instead of mem_map array.\n");
}
+static mdf_pfn_t count_bits(char *buf, int sz)
+{
+ char *p = buf;
+ int i, j;
+ mdf_pfn_t cnt = 0;
+
+ for (i = 0; i < sz; i++, p++) {
+ if (*p == 0)
+ continue;
+ else if (*p == 0xff) {
+ cnt += 8;
+ continue;
+ }
+ for (j = 0; j < 8; j++) {
+ if (*p & (1<<j))
+ cnt++;
+ }
+ }
+ return cnt;
+}
+
/*
* If using a dumpfile in kdump-compressed format as a source file
* instead of /proc/vmcore, 1st-bitmap of a new dumpfile must be
@@ -5549,6 +5570,7 @@ copy_1st_bitmap_from_memory(void)
info->name_memory, strerror(errno));
return FALSE;
}
+ pfn_memhole -= count_bits(buf, sizeof(buf));
if (write(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) {
ERRMSG("Can't write the bitmap(%s). %s\n",
info->bitmap1->file_name, strerror(errno));
@@ -5567,7 +5589,7 @@ create_1st_bitmap_file(void)
char buf[info->page_size];
mdf_pfn_t pfn, pfn_start, pfn_end, pfn_bitmap1;
unsigned long long phys_start, phys_end;
- struct timeval tv_start;
+ struct timespec ts_start;
off_t offset_page;
if (info->flag_refiltering)
@@ -5597,7 +5619,7 @@ create_1st_bitmap_file(void)
offset_page += info->page_size;
}
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
/*
* If page is on memory hole, set bit on the 1st-bitmap.
@@ -5629,7 +5651,7 @@ create_1st_bitmap_file(void)
*/
if (!info->flag_mem_usage) {
print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL);
- print_execution_time(PROGRESS_HOLES, &tv_start);
+ print_execution_time(PROGRESS_HOLES, &ts_start);
}
if (!sync_1st_bitmap())
@@ -5731,7 +5753,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int
mdf_pfn_t pfn_start_roundup, pfn_end_round;
unsigned long pfn_start_byte, pfn_end_byte;
unsigned int num_pt_loads = get_num_pt_loads();
- struct timeval tv_start;
+ struct timespec ts_start;
/*
* At first, clear all the bits on the bitmap.
@@ -5741,7 +5763,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int
/*
* If page is on memory hole, set bit on the bitmap.
*/
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
for (i = 0; get_pt_load(i, &phys_start, &phys_end, NULL, NULL); i++) {
pfn_start = MAX(paddr_to_pfn(phys_start), cycle->start_pfn);
pfn_end = MIN(paddr_to_pfn(phys_end), cycle->end_pfn);
@@ -5786,7 +5808,7 @@ create_bitmap_from_memhole(struct cycle *cycle, struct dump_bitmap *bitmap, int
* print 100 %
*/
print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr, NULL);
- print_execution_time(PROGRESS_HOLES, &tv_start);
+ print_execution_time(PROGRESS_HOLES, &ts_start);
return TRUE;
}
@@ -6045,14 +6067,14 @@ exclude_unnecessary_pages(struct cycle *cycle)
{
unsigned int mm;
struct mem_map_data *mmd;
- struct timeval tv_start;
+ struct timespec ts_start;
if (is_xen_memory() && !info->dom0_mapnr) {
ERRMSG("Can't get max domain-0 PFN for excluding pages.\n");
return FALSE;
}
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
for (mm = 0; mm < info->num_mem_map; mm++) {
@@ -6076,7 +6098,7 @@ exclude_unnecessary_pages(struct cycle *cycle)
*/
if (!info->flag_mem_usage) {
print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, info->num_mem_map, NULL);
- print_execution_time(PROGRESS_UNN_PAGES, &tv_start);
+ print_execution_time(PROGRESS_UNN_PAGES, &ts_start);
}
return TRUE;
@@ -6093,19 +6115,27 @@ copy_bitmap_buffer(void)
int
copy_bitmap_file(void)
{
- off_t offset;
+ off_t base, offset = 0;
unsigned char buf[info->page_size];
const off_t failed = (off_t)-1;
+ int fd;
+ struct disk_dump_header *dh = info->dh_memory;
- offset = 0;
+ if (info->flag_refiltering) {
+ fd = info->fd_memory;
+ base = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size) * dh->block_size;
+ base += info->len_bitmap / 2;
+ } else {
+ fd = info->bitmap1->fd;
+ base = info->bitmap1->offset;
+ }
while (offset < (info->len_bitmap / 2)) {
- if (lseek(info->bitmap1->fd, info->bitmap1->offset + offset,
- SEEK_SET) == failed) {
+ if (lseek(fd, base + offset, SEEK_SET) == failed) {
ERRMSG("Can't seek the bitmap(%s). %s\n",
info->name_bitmap, strerror(errno));
return FALSE;
}
- if (read(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) {
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
ERRMSG("Can't read the dump memory(%s). %s\n",
info->name_memory, strerror(errno));
return FALSE;
@@ -6961,7 +6991,7 @@ write_kdump_header(void)
/*
* Write common header
*/
- strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
+ memcpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
dh->header_version = 6;
dh->block_size = info->page_size;
dh->sub_hdr_size = sizeof(kh) + size_note;
@@ -7474,7 +7504,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
unsigned long frac_head, frac_tail;
off_t off_seg_load, off_memory;
Elf64_Phdr load;
- struct timeval tv_start;
+ struct timespec ts_start;
struct cycle cycle = {0};
if (!info->flag_elf_dumpfile)
@@ -7499,7 +7529,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
if (!(phnum = get_phnum_memory()))
return FALSE;
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
for (i = 0; i < phnum; i++) {
if (!get_phdr_memory(i, &load))
@@ -7547,7 +7577,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
}
if ((num_dumped % per) == 0)
- print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &ts_start);
num_dumped++;
@@ -7666,8 +7696,8 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page)
/*
* print [100 %]
*/
- print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start);
- print_execution_time(PROGRESS_COPY, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &ts_start);
+ print_execution_time(PROGRESS_COPY, &ts_start);
PROGRESS_MSG("\n");
return TRUE;
@@ -8008,8 +8038,8 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
mdf_pfn_t per;
mdf_pfn_t start_pfn, end_pfn;
struct page_desc pd;
- struct timeval tv_start;
- struct timeval last, new;
+ struct timespec ts_start;
+ struct timespec last, new;
pthread_t **threads = NULL;
struct thread_args *kdump_thread_args = NULL;
void *thread_result;
@@ -8047,7 +8077,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
per = info->num_dumpable / 10000;
per = per ? per : 1;
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
start_pfn = cycle->start_pfn;
end_pfn = cycle->end_pfn;
@@ -8095,7 +8125,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
* The next pfn is smallest pfn in all page_flag_buf.
*/
sem_wait(&info->page_flag_buf_sem);
- gettimeofday(&last, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &last);
while (1) {
current_pfn = end_pfn;
@@ -8138,7 +8168,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
* So we should recheck.
*/
if (info->page_flag_buf[consuming]->ready != FLAG_READY) {
- gettimeofday(&new, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &new);
if (new.tv_sec - last.tv_sec > WAIT_TIME) {
ERRMSG("Can't get data of pfn.\n");
goto out;
@@ -8151,7 +8181,7 @@ write_kdump_pages_parallel_cyclic(struct cache_data *cd_header,
}
if ((num_dumped % per) == 0)
- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start);
num_dumped++;
@@ -8187,8 +8217,8 @@ finish:
/*
* print [100 %]
*/
- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
- print_execution_time(PROGRESS_COPY, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start);
+ print_execution_time(PROGRESS_COPY, &ts_start);
PROGRESS_MSG("\n");
out:
@@ -8238,7 +8268,7 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag
struct page_desc pd;
unsigned char buf[info->page_size], *buf_out = NULL;
unsigned long len_buf_out;
- struct timeval tv_start;
+ struct timespec ts_start;
const off_t failed = (off_t)-1;
unsigned long len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy;
@@ -8299,12 +8329,12 @@ write_kdump_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_pag
end_pfn = info->split_end_pfn;
}
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
if ((num_dumped % per) == 0)
- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start);
/*
* Check the excluded page.
@@ -8384,8 +8414,8 @@ out:
free(wrkmem);
#endif
- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
- print_execution_time(PROGRESS_COPY, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start);
+ print_execution_time(PROGRESS_COPY, &ts_start);
return ret;
}
@@ -8747,7 +8777,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
off_t offset_data=0;
struct disk_dump_header *dh = info->dump_header;
unsigned char buf[info->page_size];
- struct timeval tv_start;
+ struct timespec ts_start;
cd_header->offset
= (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks)
@@ -8829,7 +8859,7 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
}
free_bitmap2_buffer();
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
/*
* Write the remainder.
@@ -8842,8 +8872,8 @@ write_kdump_pages_and_bitmap_cyclic(struct cache_data *cd_header, struct cache_d
/*
* print [100 %]
*/
- print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &tv_start);
- print_execution_time(PROGRESS_COPY, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, info->num_dumpable, &ts_start);
+ print_execution_time(PROGRESS_COPY, &ts_start);
PROGRESS_MSG("\n");
return TRUE;
@@ -9563,10 +9593,10 @@ exclude_xen4_user_domain(void)
int
exclude_xen_user_domain(void)
{
- struct timeval tv_start;
+ struct timespec ts_start;
int ret;
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
if (info->xen_crash_info.com &&
info->xen_crash_info.com->xen_major_version >= 4)
@@ -9578,7 +9608,7 @@ exclude_xen_user_domain(void)
* print [100 %]
*/
print_progress(PROGRESS_XEN_DOMAIN, 1, 1, NULL);
- print_execution_time(PROGRESS_XEN_DOMAIN, &tv_start);
+ print_execution_time(PROGRESS_XEN_DOMAIN, &ts_start);
return ret;
}
@@ -10502,7 +10532,7 @@ reassemble_kdump_pages(void)
struct disk_dump_header dh;
struct page_desc pd, pd_zero;
struct cache_data cd_pd, cd_data;
- struct timeval tv_start;
+ struct timespec ts_start;
char *data = NULL;
unsigned long data_buf_size = info->page_size;
@@ -10538,7 +10568,7 @@ reassemble_kdump_pages(void)
/*
* Write page header of zero-filled page.
*/
- gettimeofday(&tv_start, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
if (info->dump_level & DL_EXCLUDE_ZERO) {
/*
* makedumpfile outputs the data of zero-filled page at first
@@ -10573,7 +10603,7 @@ reassemble_kdump_pages(void)
num_dumped++;
- print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumped, num_dumpable, &ts_start);
if (lseek(fd, offset_ph_org, SEEK_SET) < 0) {
ERRMSG("Can't seek a file(%s). %s\n",
@@ -10670,8 +10700,8 @@ reassemble_kdump_pages(void)
size_eraseinfo))
goto out;
}
- print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &tv_start);
- print_execution_time(PROGRESS_COPY, &tv_start);
+ print_progress(PROGRESS_COPY, num_dumpable, num_dumpable, &ts_start);
+ print_execution_time(PROGRESS_COPY, &ts_start);
ret = TRUE;
out:
@@ -11184,6 +11214,10 @@ int show_mem_usage(void)
if (!get_page_offset())
return FALSE;
+ /* paddr_to_vaddr() on arm64 needs phys_base. */
+ if (!get_phys_base())
+ return FALSE;
+
if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
return FALSE;
diff --git a/makedumpfile.conf.5 b/makedumpfile.conf.5
index b111019..62f7379 100644
--- a/makedumpfile.conf.5
+++ b/makedumpfile.conf.5
@@ -1,4 +1,4 @@
-.TH MAKEDUMPFILE.CONF 5 "3 Jul 2018" "makedumpfile v1.6.4" "Linux System Administrator's Manual"
+.TH MAKEDUMPFILE.CONF 5 "5 Dec 2018" "makedumpfile v1.6.5" "Linux System Administrator's Manual"
.SH NAME
makedumpfile.conf \- The filter configuration file for makedumpfile(8).
.SH DESCRIPTION
diff --git a/makedumpfile.h b/makedumpfile.h
index 5ff94b8..73813ed 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -494,8 +494,8 @@ do { \
#define KVER_MAJ_SHIFT 24
#define KVER_MIN_SHIFT 16
#define KERNEL_VERSION(x,y,z) (((x) << KVER_MAJ_SHIFT) | ((y) << KVER_MIN_SHIFT) | (z))
-#define OLDEST_VERSION KERNEL_VERSION(2, 6, 15)/* linux-2.6.15 */
-#define LATEST_VERSION KERNEL_VERSION(4, 17, 0)/* linux-4.17.0 */
+#define OLDEST_VERSION KERNEL_VERSION(2, 6, 15) /* linux-2.6.15 */
+#define LATEST_VERSION KERNEL_VERSION(4, 19, 4) /* linux-4.19.4 */
/*
* vmcoreinfo in /proc/vmcore
@@ -542,6 +542,8 @@ do { \
#ifdef __aarch64__
unsigned long get_kvbase_arm64(void);
#define KVBASE get_kvbase_arm64()
+#define __START_KERNEL_map (0xffffffff80000000UL)
+
#endif /* aarch64 */
#ifdef __arm__
@@ -669,6 +671,7 @@ unsigned long get_kvbase_arm64(void);
#define _SECTION_SIZE_BITS (24)
#define _MAX_PHYSMEM_BITS_ORIG (44)
#define _MAX_PHYSMEM_BITS_3_7 (46)
+#define _MAX_PHYSMEM_BITS_4_19 (47)
#define REGION_SHIFT (60UL)
#define VMEMMAP_REGION_ID (0xfUL)
@@ -960,6 +963,8 @@ typedef unsigned long pgd_t;
static inline int stub_true() { return TRUE; }
static inline int stub_true_ul(unsigned long x) { return TRUE; }
static inline int stub_false() { return FALSE; }
+#define paddr_to_vaddr_general(X) ((X) + PAGE_OFFSET)
+
#ifdef __aarch64__
int get_phys_base_arm64(void);
int get_machdep_info_arm64(void);
@@ -967,12 +972,16 @@ unsigned long long vaddr_to_paddr_arm64(unsigned long vaddr);
int get_versiondep_info_arm64(void);
int get_xen_basic_info_arm64(void);
int get_xen_info_arm64(void);
+unsigned long get_kaslr_offset_arm64(unsigned long vaddr);
+#define paddr_to_vaddr_arm64(X) (((X) - info->phys_base) | PAGE_OFFSET)
+
#define find_vmemmap() stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_arm64(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_arm64(X)
#define get_phys_base() get_phys_base_arm64()
#define get_machdep_info() get_machdep_info_arm64()
#define get_versiondep_info() get_versiondep_info_arm64()
-#define get_kaslr_offset(X) stub_false()
+#define get_kaslr_offset(X) get_kaslr_offset_arm64(X)
#define get_xen_basic_info_arch(X) get_xen_basic_info_arm64(X)
#define get_xen_info_arch(X) get_xen_info_arm64(X)
#define is_phys_addr(X) stub_true_ul(X)
@@ -989,6 +998,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_arm(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* arm */
@@ -1003,6 +1013,7 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr);
#define get_versiondep_info() get_versiondep_info_x86()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_x86(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* x86 */
@@ -1020,6 +1031,7 @@ unsigned long long vtop4_x86_64_pagetable(unsigned long vaddr, unsigned long pag
#define get_versiondep_info() get_versiondep_info_x86_64()
#define get_kaslr_offset(X) get_kaslr_offset_x86_64(X)
#define vaddr_to_paddr(X) vtop4_x86_64(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* x86_64 */
@@ -1035,6 +1047,7 @@ int arch_crashkernel_mem_size_ppc64(void);
#define get_versiondep_info() get_versiondep_info_ppc64()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_ppc64(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() arch_crashkernel_mem_size_ppc64()
#endif /* powerpc64 */
@@ -1048,6 +1061,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_ppc(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* powerpc32 */
@@ -1062,6 +1076,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* s390x */
@@ -1076,6 +1091,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) stub_false()
#define vaddr_to_paddr(X) vaddr_to_paddr_ia64(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define VADDR_REGION(X) (((unsigned long)(X)) >> REGION_SHIFT)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
@@ -1090,6 +1106,7 @@ unsigned long long vaddr_to_paddr_sparc64(unsigned long vaddr);
#define get_phys_base() get_phys_base_sparc64()
#define get_versiondep_info() get_versiondep_info_sparc64()
#define vaddr_to_paddr(X) vaddr_to_paddr_sparc64(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
#define is_phys_addr(X) stub_true_ul(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* sparc64 */
diff --git a/makedumpfile.spec b/makedumpfile.spec
index 88bb555..7ebd2c4 100644
--- a/makedumpfile.spec
+++ b/makedumpfile.spec
@@ -1,13 +1,13 @@
Name: makedumpfile
Summary: makedumpfile package
-Version: 1.6.4
+Version: 1.6.5
Release: 1
Group: Applications/Text
License: GPL
Source: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-root
Distribution: Linux 2.6 or greater
-Packager: Atsushi Kumagai <ats-kumagai@wm.jp.nec.com>
+Packager: Kazuhito Hagio <k-hagio@ab.jp.nec.com>
ExclusiveOS: Linux
ExclusiveArch: i386 ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64
Buildroot: %{_tmppath}/%{name}-root
diff --git a/print_info.c b/print_info.c
index 6bfcd11..0be12ea 100644
--- a/print_info.c
+++ b/print_info.c
@@ -19,6 +19,8 @@
#define PROGRESS_MAXLEN "50"
+#define NSEC_PER_SEC 1000000000L
+
int message_level;
int flag_strerr_message;
int flag_ignore_r_char; /* 0: '\r' is effective. 1: not effective. */
@@ -298,7 +300,7 @@ print_usage(void)
MSG(" necessary to specify [-x VMLINUX] or [-i VMCOREINFO].\n");
MSG("\n");
MSG(" [--mem-usage]:\n");
- MSG(" This option is only for x86_64.\n");
+ MSG(" This option is currently supported on x86_64, arm64, ppc64 and s390x.\n");
MSG(" This option is used to show the page numbers of current system in different\n");
MSG(" use. It should be executed in 1st kernel. By the help of this, user can know\n");
MSG(" how many pages is dumpable when different dump_level is specified. It analyzes\n");
@@ -338,16 +340,16 @@ print_usage(void)
MSG("\n");
}
-static void calc_delta(struct timeval *tv_start, struct timeval *delta)
+static void calc_delta(struct timespec *ts_start, struct timespec *delta)
{
- struct timeval tv_end;
+ struct timespec ts_end;
- gettimeofday(&tv_end, NULL);
- delta->tv_sec = tv_end.tv_sec - tv_start->tv_sec;
- delta->tv_usec = tv_end.tv_usec - tv_start->tv_usec;
- if (delta->tv_usec < 0) {
+ clock_gettime(CLOCK_MONOTONIC, &ts_end);
+ delta->tv_sec = ts_end.tv_sec - ts_start->tv_sec;
+ delta->tv_nsec = ts_end.tv_nsec - ts_start->tv_nsec;
+ if (delta->tv_nsec < 0) {
delta->tv_sec--;
- delta->tv_usec += 1000000;
+ delta->tv_nsec += NSEC_PER_SEC;
}
}
@@ -371,14 +373,14 @@ static int eta_to_human_short (unsigned long secs, char* msg)
void
-print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start)
+print_progress(const char *msg, unsigned long current, unsigned long end, struct timespec *start)
{
unsigned progress; /* in promilles (tenths of a percent) */
time_t tm;
static time_t last_time = 0;
static unsigned int lapse = 0;
static const char *spinner = "/|\\-";
- struct timeval delta;
+ struct timespec delta;
unsigned long eta;
char eta_msg[16] = " ";
@@ -393,7 +395,7 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct
if (start != NULL && progress != 0) {
calc_delta(start, &delta);
- eta = 1000 * delta.tv_sec + delta.tv_usec / 1000;
+ eta = 1000 * delta.tv_sec + delta.tv_nsec / (NSEC_PER_SEC / 1000);
eta = eta / progress - delta.tv_sec;
eta_to_human_short(eta, eta_msg);
}
@@ -411,12 +413,12 @@ print_progress(const char *msg, unsigned long current, unsigned long end, struct
}
void
-print_execution_time(char *step_name, struct timeval *tv_start)
+print_execution_time(char *step_name, struct timespec *ts_start)
{
- struct timeval delta;
+ struct timespec delta;
- calc_delta(tv_start, &delta);
+ calc_delta(ts_start, &delta);
REPORT_MSG("STEP [%s] : %ld.%06ld seconds\n",
- step_name, delta.tv_sec, delta.tv_usec);
+ step_name, delta.tv_sec, delta.tv_nsec / 1000);
}
diff --git a/print_info.h b/print_info.h
index 1ce3593..49b70f4 100644
--- a/print_info.h
+++ b/print_info.h
@@ -17,7 +17,7 @@
#define _PRINT_INFO_H
#include <stdio.h>
-#include <sys/time.h>
+#include <time.h>
extern int message_level;
extern int flag_strerr_message;
@@ -25,9 +25,9 @@ extern int flag_ignore_r_char;
void show_version(void);
void print_usage(void);
-void print_progress(const char *msg, unsigned long current, unsigned long end, struct timeval *start);
+void print_progress(const char *msg, unsigned long current, unsigned long end, struct timespec *start);
-void print_execution_time(char *step_name, struct timeval *tv_start);
+void print_execution_time(char *step_name, struct timespec *ts_start);
/*
* Message texts
diff --git a/sadump_info.c b/sadump_info.c
index dd50d48..46867ce 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -311,7 +311,7 @@ sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size)
}
strncpy(info->release, info->system_utsname.release,
- strlen(info->system_utsname.release) + 1);
+ STRLEN_OSRELEASE);
write_vmcoreinfo_data();
@@ -2395,7 +2395,7 @@ sadump_kdump_backup_region_init(void)
elfcorehdr_p = 0;
for (i = 0; i < ARRAY_LENGTH(kimage.segment); ++i) {
char e_ident[EI_NIDENT];
- unsigned mem;
+ unsigned long mem;
mem=ULONG(buf+i*SIZE(kexec_segment)+OFFSET(kexec_segment.mem));
if (!mem)