[PATCH] diskdump: use mmap/madvise to improve the start-up
by Huang Shijie
1.) The bitmap of vmcore file can be very big in the server kernel panic,
such as over 256M.
This patch uses mmap/madvise to improve the read speed
of the bitmap in the non-FLAT_FORMAT code path.
Use MADV_SEQUENTIAL for madvise, it will trigger aggressively
readahead for reading the bitmap.
2.) Test.
The files:
vmlinux: 272M
vmcore : 23G (bitmap is 281018368 bytes)
#cat ./commands.txt
quit
Before this patch:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 0m55.217s
user 0m15.114s
sys 0m3.560s
............................
After this patch:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 0m46.781s
user 0m19.693s
sys 0m1.642s
............................
Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
---
This patch is based on patch:
diskdump: Optimize the boot time
---
diskdump.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/diskdump.c b/diskdump.c
index d30db9d..c60b283 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -724,10 +724,6 @@ restart:
offset = (off_t)block_size * (1 + header->sub_hdr_size);
- if ((dd->bitmap = malloc(bitmap_len)) == NULL)
- error(FATAL, "%s: cannot malloc bitmap buffer\n",
- DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
-
dd->dumpable_bitmap = calloc(bitmap_len, 1);
if (CRASHDEBUG(8))
@@ -736,30 +732,23 @@ restart:
(ulonglong)offset);
if (FLAT_FORMAT()) {
+ if ((dd->bitmap = malloc(bitmap_len)) == NULL)
+ error(FATAL, "%s: cannot malloc bitmap buffer\n",
+ DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
+
if (!read_flattened_format(dd->dfd, offset, dd->bitmap, bitmap_len)) {
error(INFO, "%s: cannot read memory bitmap\n",
DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
goto err;
}
} else {
- if (lseek(dd->dfd, offset, SEEK_SET) == failed) {
- error(INFO, "%s: cannot lseek memory bitmap\n",
+ dd->bitmap = mmap(NULL, bitmap_len, PROT_READ,
+ MAP_SHARED, dd->dfd, offset);
+ if (dd->bitmap == MAP_FAILED)
+ error(FATAL, "%s: cannot mmap bitmap buffer\n",
DISKDUMP_VALID() ? "diskdump" : "compressed kdump");
- goto err;
- }
- bufptr = dd->bitmap;
- len = bitmap_len;
- while (len) {
- bytes_read = read(dd->dfd, bufptr, len);
- if (bytes_read <= 0) {
- error(INFO, "%s: cannot read memory bitmap\n",
- DISKDUMP_VALID() ? "diskdump"
- : "compressed kdump");
- goto err;
- }
- len -= bytes_read;
- bufptr += bytes_read;
- }
+
+ madvise(dd->bitmap, bitmap_len, MADV_SEQUENTIAL);
}
if (dump_is_partial(header))
@@ -920,8 +909,12 @@ err:
free(sub_header);
if (sub_header_kdump)
free(sub_header_kdump);
- if (dd->bitmap)
- free(dd->bitmap);
+ if (dd->bitmap) {
+ if (FLAT_FORMAT())
+ free(dd->bitmap);
+ else
+ munmap(dd->bitmap, dd->bitmap_len);
+ }
if (dd->dumpable_bitmap)
free(dd->dumpable_bitmap);
if (dd->notes_buf)
--
2.30.2
2 years, 5 months
invalid structure member offset: page_active #115
by sholck
Hello:
A patch named 0001-Fix-for-kmem-s-S-on-Linux-5.17.0.patch to fix "invalid structure member offset: page_active #115",
you can get from attachment.
================================================================
>From c8bd4ad430abdfe2dc86149694f424ea24f2b7ec Mon Sep 17 00:00:00 2001
From: xiaer1921 <xiaer1921(a)gmail.com>
Date: Tue, 29 Mar 2022 20:03:03 +0800
Subject: [PATCH] Fix for "kmem -s|-S" on Linux 5.17.0+
Since the following kernel commits split slab info from struct page
into struct slab, crash cannot get several slab related offsets from
struct page.
d122019bf061 ("mm: Split slab into its own type")
401fb12c68c2 ("mm: Differentiate struct slab fields by sl*b implementations")
07f910f9b729 ("mm: Remove slab from struct page")
Without the patch, "kmem -s|-S" options cannot work
correctly with the following errors:
crash> kmem -s
kmem: invalid structure member offset: page_active
FILE: memory.c LINE: 12225 FUNCTION: verify_slab_overload_page()
[/usr/bin/crash] error trace: 532526 => 53353a => 5e0a6a => 5e09dc
[Detaching after fork from child process 28299]
5e09dc: OFFSET_verify.part.36+92
[Detaching after fork from child process 28301]
5e0a6a: OFFSET_verify+58
[Detaching after fork from child process 28303]
53353a: verify_slab_overload_page+588
[Detaching after fork from child process 28305]
532526: do_slab_chain_slab_overload_page+1171
kmem: invalid structure member offset: page_active
FILE: memory.c LINE: 12225 FUNCTION: verify_slab_overload_page()
Signed-off-by: xiaer1921 <xiaer1921(a)gmail.com>
---
memory.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/memory.c b/memory.c
index 8448ddc..388b12d 100644
--- a/memory.c
+++ b/memory.c
@@ -680,6 +680,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(slab_s_mem, "slab", "s_mem");
MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse");
MEMBER_OFFSET_INIT(slab_free, "slab", "free");
+ MEMBER_OFFSET_INIT(page_s_mem, "slab", "s_mem");
+ MEMBER_OFFSET_INIT(page_active, "slab", "active");
/*
* slab members were moved to an anonymous union in 2.6.39.
*/
@@ -691,6 +693,10 @@ vm_init(void)
ANON_MEMBER_OFFSET_INIT(slab_inuse, "slab", "inuse");
if (INVALID_MEMBER(slab_free))
ANON_MEMBER_OFFSET_INIT(slab_free, "slab", "free");
+ if (INVALID_MEMBER(page_s_mem))
+ ANON_MEMBER_OFFSET_INIT(page_s_mem, "slab", "s_mem");
+ if (INVALID_MEMBER(page_active))
+ ANON_MEMBER_OFFSET_INIT(page_active, "slab", "active");
}
MEMBER_OFFSET_INIT(array_cache_avail, "array_cache", "avail");
--
2.7.4
================================================================
Thanks.
2 years, 5 months
[PATCH v2] diskdump: Optimize the boot time
by Huang Shijie
1.) The vmcore file maybe very big.
For example, I have a vmcore file which is over 23G,
and the panic kernel had 767.6G memory,
its max_sect_len is 4468736.
Current code costs too much time to do the following loop:
..............................................
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
if (page_is_dumpable(pfn))
dd->valid_pages[i]++;
..............................................
For my case, it costs about 56 seconds to finish the
big loop.
This patch moves the hweightXX macros to defs.h,
and uses hweight64 to optimize the loop.
For my vmcore, the loop only costs about one second now.
2.) Tests result:
# cat ./commands.txt
quit
Before:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 1m54.259s
user 1m12.494s
sys 0m3.857s
............................
After this patch:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 0m55.217s
user 0m15.114s
sys 0m3.560s
............................
Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
---
v1 --> v2:
1.) change u64 to ulonglong.
2.) compile this patch in x86_64.
---
defs.h | 20 ++++++++++++++++++++
diskdump.c | 12 +++++++++---
sbitmap.c | 19 -------------------
3 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/defs.h b/defs.h
index 81ac049..1e8360d 100644
--- a/defs.h
+++ b/defs.h
@@ -4531,6 +4531,26 @@ struct machine_specific {
#define NUM_IN_BITMAP(bitmap, x) (bitmap[(x)/BITS_PER_LONG] & NUM_TO_BIT(x))
#define SET_BIT(bitmap, x) (bitmap[(x)/BITS_PER_LONG] |= NUM_TO_BIT(x))
+static inline unsigned int __const_hweight8(unsigned long w)
+{
+ return
+ (!!((w) & (1ULL << 0))) +
+ (!!((w) & (1ULL << 1))) +
+ (!!((w) & (1ULL << 2))) +
+ (!!((w) & (1ULL << 3))) +
+ (!!((w) & (1ULL << 4))) +
+ (!!((w) & (1ULL << 5))) +
+ (!!((w) & (1ULL << 6))) +
+ (!!((w) & (1ULL << 7)));
+}
+
+#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
+#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
+#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
+
+#define hweight32(w) __const_hweight32(w)
+#define hweight64(w) __const_hweight64(w)
+
/*
* precision lengths for fprintf
*/
diff --git a/diskdump.c b/diskdump.c
index d567427..ff1e9a3 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -547,6 +547,7 @@ read_dump_header(char *file)
ulong pfn;
int i, j, max_sect_len;
int is_split = 0;
+ ulonglong tmp, *bitmap;
if (block_size < 0)
return FALSE;
@@ -899,11 +900,16 @@ restart:
dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1);
dd->max_sect_len = max_sect_len;
+
+ /* It is safe to convert it to (ulonglong *). */
+ bitmap = (ulonglong *)dd->dumpable_bitmap;
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
- for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
- if (page_is_dumpable(pfn))
- dd->valid_pages[i]++;
+ for (j = 0; j < BITMAP_SECT_LEN; j += 64, pfn += 64) {
+ tmp = bitmap[pfn >> 6];
+ if (tmp)
+ dd->valid_pages[i] += hweight64(tmp);
+ }
}
return TRUE;
diff --git a/sbitmap.c b/sbitmap.c
index 286259f..96a61e6 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -49,25 +49,6 @@ struct sbitmapq_data {
static uint sb_flags = 0;
-static inline unsigned int __const_hweight8(unsigned long w)
-{
- return
- (!!((w) & (1ULL << 0))) +
- (!!((w) & (1ULL << 1))) +
- (!!((w) & (1ULL << 2))) +
- (!!((w) & (1ULL << 3))) +
- (!!((w) & (1ULL << 4))) +
- (!!((w) & (1ULL << 5))) +
- (!!((w) & (1ULL << 6))) +
- (!!((w) & (1ULL << 7)));
-}
-
-#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
-#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
-#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
-
-#define hweight32(w) __const_hweight32(w)
-#define hweight64(w) __const_hweight64(w)
#define BIT(nr) (1UL << (nr))
--
2.30.2
2 years, 5 months
[PATCH] diskdump: Optimize the boot time
by Huang Shijie
1.) The vmcore file maybe very big.
For example, I have a vmcore file which is over 23G,
and the panic kernel had 767.6G memory,
its max_sect_len is 4468736.
Current code costs too much time to do the following loop:
..............................................
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
if (page_is_dumpable(pfn))
dd->valid_pages[i]++;
..............................................
For my case, it costs about 56 seconds to finish the
big loop.
This patch moves the hweightXX macros to defs.h,
and uses hweight64 to optimize the loop.
For my vmcore, the loop only costs about one second now.
2.) Tests result:
# cat ./commands.txt
quit
Before:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 1m54.259s
user 1m12.494s
sys 0m3.857s
............................
After this patch:
#echo 3 > /proc/sys/vm/drop_caches;
#time ./crash -i ./commands.txt /root/t/vmlinux /root/t/vmcore > /dev/null 2>&1
............................
real 0m55.217s
user 0m15.114s
sys 0m3.560s
............................
Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
---
defs.h | 20 ++++++++++++++++++++
diskdump.c | 12 +++++++++---
sbitmap.c | 19 -------------------
3 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/defs.h b/defs.h
index 81ac049..1e8360d 100644
--- a/defs.h
+++ b/defs.h
@@ -4531,6 +4531,26 @@ struct machine_specific {
#define NUM_IN_BITMAP(bitmap, x) (bitmap[(x)/BITS_PER_LONG] & NUM_TO_BIT(x))
#define SET_BIT(bitmap, x) (bitmap[(x)/BITS_PER_LONG] |= NUM_TO_BIT(x))
+static inline unsigned int __const_hweight8(unsigned long w)
+{
+ return
+ (!!((w) & (1ULL << 0))) +
+ (!!((w) & (1ULL << 1))) +
+ (!!((w) & (1ULL << 2))) +
+ (!!((w) & (1ULL << 3))) +
+ (!!((w) & (1ULL << 4))) +
+ (!!((w) & (1ULL << 5))) +
+ (!!((w) & (1ULL << 6))) +
+ (!!((w) & (1ULL << 7)));
+}
+
+#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
+#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
+#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
+
+#define hweight32(w) __const_hweight32(w)
+#define hweight64(w) __const_hweight64(w)
+
/*
* precision lengths for fprintf
*/
diff --git a/diskdump.c b/diskdump.c
index d567427..d30db9d 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -547,6 +547,7 @@ read_dump_header(char *file)
ulong pfn;
int i, j, max_sect_len;
int is_split = 0;
+ u64 tmp, *bitmap;
if (block_size < 0)
return FALSE;
@@ -899,11 +900,16 @@ restart:
dd->valid_pages = calloc(sizeof(ulong), max_sect_len + 1);
dd->max_sect_len = max_sect_len;
+
+ /* It is safe to convert it to (u64*). */
+ bitmap = (u64 *)dd->dumpable_bitmap;
for (i = 1; i < max_sect_len + 1; i++) {
dd->valid_pages[i] = dd->valid_pages[i - 1];
- for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
- if (page_is_dumpable(pfn))
- dd->valid_pages[i]++;
+ for (j = 0; j < BITMAP_SECT_LEN; j += 64, pfn += 64) {
+ tmp = bitmap[pfn >> 6];
+ if (tmp)
+ dd->valid_pages[i] += hweight64(tmp);
+ }
}
return TRUE;
diff --git a/sbitmap.c b/sbitmap.c
index 286259f..96a61e6 100644
--- a/sbitmap.c
+++ b/sbitmap.c
@@ -49,25 +49,6 @@ struct sbitmapq_data {
static uint sb_flags = 0;
-static inline unsigned int __const_hweight8(unsigned long w)
-{
- return
- (!!((w) & (1ULL << 0))) +
- (!!((w) & (1ULL << 1))) +
- (!!((w) & (1ULL << 2))) +
- (!!((w) & (1ULL << 3))) +
- (!!((w) & (1ULL << 4))) +
- (!!((w) & (1ULL << 5))) +
- (!!((w) & (1ULL << 6))) +
- (!!((w) & (1ULL << 7)));
-}
-
-#define __const_hweight16(w) (__const_hweight8(w) + __const_hweight8((w) >> 8))
-#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
-#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
-
-#define hweight32(w) __const_hweight32(w)
-#define hweight64(w) __const_hweight64(w)
#define BIT(nr) (1UL << (nr))
--
2.30.2
2 years, 5 months
crash: read error on type: "memory section root table"
by Agrain Patrick
Hello,
Sorry to cross post on both ML, I'm not sure which one would be the most suitable.
Issue on analysis with crash-7.3.1 on a Centos 8 machine:
crash: read error: kernel virtual address: ffff8f4fff7fc000 type: "memory section root table"
Crash machine has a Rocky Linux 8.5 based kernel with following config options:
* CONFIG_RANDOMIZE_BASE=y
* CONFIG_RANDOMIZE_MEMORY=y
* CONFIG_SPARSEMEM_MANUAL=y
* CONFIG_SPARSEMEM=y
* CONFIG_SPARSEMEM_EXTREME=y
* CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
* CONFIG_KEXEC_CORE=y
* CONFIG_KEXEC=y
* CONFIG_KEXEC_FILE=y
Kexec-tools package is from Centos Stream repo: kexec-tools-2.0.20-68.el8.2.5ale.x86_64
/proc/vmcore is packaged with :
/sbin/makedumpfile -D -d 0 -c --message-level 15 /proc/vmcore /tmpd/crashdump-${linux_ver}-${date_time}
At kernel panic, I get:
Dumping memory to crash partition
This may take a while, please wait...
makedumpfile: version 1.7.0 (released on 8 Nov 2021)
command line: /sbin/makedumpfile -D -d 0 -c --message-level 15 /proc/vmcore /tmpd/crashdump--20220329-1538
sadump: does not have partition header
sadump: read dump device as unknown format
sadump: unknown format
phys_start phys_end virt_start virt_end
LOAD[ 0] 8000000 9a2c000 ffffffff8a400000 ffffffff8be2c000
LOAD[ 1] 100000 3b000000 ffff8f4fc0100000 ffff8f4ffb000000
LOAD[ 2] 3d800000 3e341000 ffff8f4ffd800000 ffff8f4ffe341000
LOAD[ 3] 3ed7b000 3eee2000 ffff8f4ffed7b000 ffff8f4ffeee2000
LOAD[ 4] 3f63a000 3f800000 ffff8f4fff63a000 ffff8f4fff800000
Linux kdump
VMCOREINFO :
OSRELEASE=4.18.0-348.12.2.el8_5-ale
PAGESIZE=4096
page_size : 4096
SYMBOL(init_uts_ns)=ffffffff8b653600
SYMBOL(node_online_map)=ffffffff8b7630a8
SYMBOL(swapper_pg_dir)=ffffffff8b64c000
SYMBOL(_stext)=ffffffff8a400000
SYMBOL(vmap_area_list)=ffffffff8b6a47a0
SYMBOL(mem_map)=ffffffff8bd25828
SYMBOL(contig_page_data)=ffffffff8b726600
SYMBOL(mem_section)=ffff8f4fff7fc000
LENGTH(mem_section)=2048
SIZE(mem_section)=16
OFFSET(mem_section.section_mem_map)=0
SIZE(page)=64
SIZE(pglist_data)=5696
SIZE(zone)=1216
SIZE(free_area)=72
SIZE(list_head)=16
SIZE(nodemask_t)=8
OFFSET(page.flags)=0
OFFSET(page._refcount)=52
OFFSET(page.mapping)=24
OFFSET(page.lru)=8
OFFSET(page._mapcount)=48
OFFSET(page.private)=40
OFFSET(page.compound_dtor)=16
OFFSET(page.compound_order)=17
OFFSET(page.compound_head)=8
OFFSET(pglist_data.node_zones)=0
OFFSET(pglist_data.nr_zones)=4944
OFFSET(pglist_data.node_start_pfn)=4952
OFFSET(pglist_data.node_spanned_pages)=4968
OFFSET(pglist_data.node_id)=4976
OFFSET(zone.free_area)=192
OFFSET(zone.vm_stat)=1104
OFFSET(zone.spanned_pages)=96
OFFSET(free_area.free_list)=0
OFFSET(list_head.next)=0
OFFSET(list_head.prev)=8
OFFSET(vmap_area.va_start)=0
OFFSET(vmap_area.list)=40
LENGTH(zone.free_area)=11
SYMBOL(log_buf)=ffffffff8b67d3c0
SYMBOL(log_buf_len)=ffffffff8b67d3bc
SYMBOL(log_first_idx)=ffffffff8bd1a3d8
SYMBOL(clear_idx)=ffffffff8bd1a3a4
SYMBOL(log_next_idx)=ffffffff8bd1a3c8
SIZE(printk_log)=16
OFFSET(printk_log.ts_nsec)=0
OFFSET(printk_log.len)=8
OFFSET(printk_log.text_len)=10
OFFSET(printk_log.dict_len)=12
LENGTH(free_area.free_list)=4
NUMBER(NR_FREE_PAGES)=0
NUMBER(PG_lru)=5
NUMBER(PG_private)=12
NUMBER(PG_swapcache)=9
NUMBER(PG_swapbacked)=18
NUMBER(PG_slab)=8
NUMBER(PG_head_mask)=32768
NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE)=-129
NUMBER(HUGETLB_PAGE_DTOR)=2
NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE)=-257
SYMBOL(alcatel_dump_info)=ffffffff8b647000
NUMBER(phys_base)=-37748736
SYMBOL(init_top_pgt)=ffffffff8b64c000
NUMBER(pgtable_l5_enabled)=0
KERNELOFFSET=9400000
NUMBER(KERNEL_IMAGE_SIZE)=1073741824
NUMBER(sme_mask)=0
CRASHTIME=1648561077
phys_base : fffffffffdc00000 (vmcoreinfo)
max_mapnr : 3f800
There is enough free memory to be done in one cycle.
Buffer size for the cyclic mode: 65024
page_offset : ffff8f4fc0000000 (pt_load)
num of NODEs : 1
Memory type : SPARSEMEM_EX
mem_map pfn_start pfn_end
mem_map[ 0] ffff8f4ffa000000 0 8000
mem_map[ 1] ffff8f4ffa200000 8000 10000
mem_map[ 2] ffff8f4ffa400000 10000 18000
mem_map[ 3] ffff8f4ffa600000 18000 20000
mem_map[ 4] ffff8f4ffa800000 20000 28000
mem_map[ 5] ffff8f4ffaa00000 28000 30000
mem_map[ 6] ffff8f4ffac00000 30000 38000
mem_map[ 7] ffff8f4ffae00000 38000 3f800
mmap() is available on the kernel.
Copying data : [100.0 %] | eta: 0s
Writing erase info...
offset_eraseinfo: ca157f3, size_eraseinfo: 0
The dumpfile is saved to /tmpd/crashdump--20220329-1538.
makedumpfile Completed.
Rebooting the system...
And latest logs from a 'crash -d 7' command are:
<...>
kernel NR_CPUS: 2
<readmem: ffffffff8bd25820, KVADDR, "high_memory", 8, (FOE), 55e05ecb3608>
<read_diskdump: addr: ffffffff8bd25820 paddr: 9925820 cnt: 8>
PAGESIZE=4096
mem_section_size = 16384
NR_SECTION_ROOTS = 2048
NR_MEM_SECTIONS = 524288
SECTIONS_PER_ROOT = 256
SECTION_ROOT_MASK = 0xff
PAGES_PER_SECTION = 32768
<readmem: ffffffff8bd26db0, KVADDR, "mem_section", 8, (FOE), 7ffdbf96a440>
<read_diskdump: addr: ffffffff8bd26db0 paddr: 9926db0 cnt: 8>
<readmem: ffff8f4fff7fc000, KVADDR, "memory section root table", 16384, (FOE), 55e06391b840>
<read_diskdump: addr: ffff8f4fff7fc000 paddr: 3f7fc000 cnt: 4096>
crash: read error: kernel virtual address: ffff8f4fff7fc000 type: "memory section root table"
The address (ffff8f4fff7fc000) seems to be inside the LOAD[4] range and is recorded as 'mem_section' with VMCOREINFO.
What's wrong ? Where should I look at ?
Thanks.
Best regards,
Patrick Agrain
2 years, 5 months
[PATCH] Fix the failure of resolving ".rodata" on s390x
by Lianbo Jiang
The commit <cd8954023bd4> broke crash-utility on s390x and got the
following error:
crash: cannot resolve ".rodata"
The reason is that all symbols containing a "." may be filtered out
on s390x. To prevent the current failure, a simple way is to check
whether the symbol ".rodata" exists before calculating the value of
a symbol.
Fixes: cd8954023bd4 ("kernel: fix start-up time degradation caused by strings command")
Reported-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
kernel.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel.c b/kernel.c
index 92434a3ffe2d..b504564846c7 100644
--- a/kernel.c
+++ b/kernel.c
@@ -11790,6 +11790,9 @@ int get_linux_banner_from_vmlinux(char *buf, size_t size)
struct bfd_section *sect;
long offset;
+ if (!symbol_exists(".rodata"))
+ return FALSE;
+
sect = bfd_get_section_by_name(st->bfd, ".rodata");
if (!sect)
return FALSE;
--
2.20.1
2 years, 5 months
Re: [Crash-utility] [PATCH] kernel: fix start-up time degradation caused by strings command
by lijiang
On Mon, Mar 28, 2022 at 5:04 PM <crash-utility-request(a)redhat.com> wrote:
> Date: Mon, 28 Mar 2022 11:03:38 +0200
> From: Alexander Egorenkov <egorenar(a)linux.ibm.com>
> To: "d.hatayama(a)fujitsu.com" <d.hatayama(a)fujitsu.com>,
> "crash-utility(a)redhat.com" <crash-utility(a)redhat.com>
> Subject: Re: [Crash-utility] [PATCH] kernel: fix start-up time
> degradation caused by strings command
> Message-ID: <87ee2m4ff9.fsf(a)oc8242746057.ibm.com>
> Content-Type: text/plain
>
> "d.hatayama(a)fujitsu.com" <d.hatayama(a)fujitsu.com> writes:
>
> > verify_namelist() uses strings command and scans full part of vmlinux
> > file to find linux_banner string. However, vmlinux file is quite large
> > these days, reaching over 500MB. As a result, this degradates start-up
> > time of crash command 10 or more seconds. (Of course, this depends on
> > machines you use for investigation, but I guess typically we cannot
> > use such powerful machines to investigate crash dump...)
> >
> > To resolve this issue, let's use bfd library and read linux_banner
> > string in vmlinux file directly.
> >
> > A simple benchmark shows the following result:
> >
> > Without the fix:
> >
> > # cat ./commands.txt
> > quit
> > # time ./crash -i ./commands.txt \
> > /usr/lib/debug/lib/modules/5.16.15-201.fc35.x86_64/vmlinux \
> > /var/crash/*/vmcore >/dev/null 2>&1
> >
> > real 0m20.251s
> > user 0m19.022s
> > sys 0m1.054s
> >
> > With the fix:
> >
> > # time ./crash -i ./commands.txt \
> > /usr/lib/debug/lib/modules/5.16.15-201.fc35.x86_64/vmlinux \
> > /var/crash/*/vmcore >/dev/null 2>&1
> >
> > real 0m6.528s
> > user 0m6.143s
> > sys 0m0.431s
> >
> > Note that this commit keeps the original logic that uses strings
> > command for backward compatibility for in case.
> >
> > Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)fujitsu.com>
> > ---
> > Makefile | 2 +-
> > kernel.c | 41 +++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 42 insertions(+), 1 deletion(-)
> >
> > diff --git a/Makefile b/Makefile
> > index 007d030..e520b12 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -364,7 +364,7 @@ task.o: ${GENERIC_HFILES} task.c
> > ${CC} -c ${CRASH_CFLAGS} task.c ${WARNING_OPTIONS} ${WARNING_ERROR}
> >
> > kernel.o: ${GENERIC_HFILES} kernel.c
> > - ${CC} -c ${CRASH_CFLAGS} kernel.c ${WARNING_OPTIONS}
> ${WARNING_ERROR}
> > + ${CC} -c ${CRASH_CFLAGS} kernel.c -I${BFD_DIRECTORY}
> -I${GDB_INCLUDE_DIRECTORY} ${WARNING_OPTIONS} ${WARNING_ERROR}
> >
> > printk.o: ${GENERIC_HFILES} printk.c
> > ${CC} -c ${CRASH_CFLAGS} printk.c ${WARNING_OPTIONS}
> ${WARNING_ERROR}
> > diff --git a/kernel.c b/kernel.c
> > index 1c63447..92434a3 100644
> > --- a/kernel.c
> > +++ b/kernel.c
> > @@ -23,6 +23,11 @@
> > #include <ctype.h>
> > #include <stdbool.h>
> > #include "xendump.h"
> > +#if defined(GDB_7_6) || defined(GDB_10_2)
> > +#define __CONFIG_H__ 1
> > +#include "config.h"
> > +#endif
> > +#include "bfd.h"
> >
> > static void do_module_cmd(ulong, char *, ulong, char *, char *);
> > static void show_module_taint(void);
> > @@ -97,6 +102,7 @@ static void dump_printk_safe_seq_buf(int);
> > static char *vmcoreinfo_read_string(const char *);
> > static void check_vmcoreinfo(void);
> > static int is_pvops_xen(void);
> > +static int get_linux_banner_from_vmlinux(char *, size_t);
> >
> >
> > /*
> > @@ -1324,6 +1330,12 @@ verify_namelist()
> > target_smp = strstr(kt->utsname.version, " SMP ") ? TRUE : FALSE;
> > namelist_smp = FALSE;
> >
> > + if (get_linux_banner_from_vmlinux(buffer, sizeof(buffer)) &&
> > + strstr(buffer, kt->proc_version)) {
> > + found = TRUE;
> > + goto found;
> > + }
> > +
> > sprintf(command, "/usr/bin/strings %s", namelist);
> > if ((pipe = popen(command, "r")) == NULL) {
> > error(INFO, "%s: %s\n", namelist, strerror(errno));
> > @@ -1384,6 +1396,7 @@ verify_namelist()
> > }
> > }
> >
> > +found:
> > if (found) {
> > if (CRASHDEBUG(1)) {
> > fprintf(fp, "verify_namelist:\n");
> > @@ -11770,3 +11783,31 @@ check_vmcoreinfo(void)
> > }
> > }
> > }
> > +
> > +static
> > +int get_linux_banner_from_vmlinux(char *buf, size_t size)
> > +{
> > + struct bfd_section *sect;
> > + long offset;
> > +
> > + sect = bfd_get_section_by_name(st->bfd, ".rodata");
> > + if (!sect)
> > + return FALSE;
> > +
> > + /*
> > + * Although symbol_value() returns dynamic symbol value that
> > + * is affected by kaslr, which is different from static symbol
> > + * value in vmlinux file, but relative offset to linux_banner
> > + * object in .rodata section is idential.
> > + */
> > + offset = symbol_value("linux_banner") - symbol_value(".rodata");
> > +
> > + if (!bfd_get_section_contents(st->bfd,
> > + sect,
> > + buf,
> > + offset,
> > + size))
> > + return FALSE;
> > +
> > + return TRUE;
> > +}
> > --
> > 2.31.1
> >
> >
> >
> > --
> > Crash-utility mailing list
> > Crash-utility(a)redhat.com
> > https://listman.redhat.com/mailman/listinfo/crash-utility
> > Contribution Guidelines: https://github.com/crash-utility/crash/wiki
>
> Hi,
>
> this patch broke crash-utility on s390.
> When i try to open a dump file, then i get this error message:
>
> crash: cannot resolve ".rodata"
>
>
Thank you for pointing out this issue, Alex.
Any idea why .rodata symbol is missing ?
> Maybe test for its existence first ?
>
Does the following patch work for you?
diff --git a/kernel.c b/kernel.c
index 92434a3..b504564 100644
--- a/kernel.c
+++ b/kernel.c
@@ -11790,6 +11790,9 @@ int get_linux_banner_from_vmlinux(char *buf, size_t
size)
struct bfd_section *sect;
long offset;
+ if (!symbol_exists(".rodata"))
+ return FALSE;
+
sect = bfd_get_section_by_name(st->bfd, ".rodata");
if (!sect)
return FALSE;
Thanks.
Lianbo
Regards
> Alex
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> --
> Crash-utility mailing list
> Crash-utility(a)redhat.com
> https://listman.redhat.com/mailman/listinfo/crash-utility
>
>
> ------------------------------
>
> End of Crash-utility Digest, Vol 198, Issue 33
> **********************************************
>
>
2 years, 5 months
Re: [Crash-utility] [PATCH 1/2] Add a new helper arm64_get_pkd
by lijiang
Hi, Shijie
On Fri, Mar 18, 2022 at 8:00 PM <crash-utility-request(a)redhat.com> wrote:
> Date: Fri, 18 Mar 2022 14:09:36 +0000
> From: Huang Shijie <shijie(a)os.amperecomputing.com>
> To: k-hagio-ab(a)nec.com
> Cc: patches(a)amperecomputing.com, zwang(a)amperecomputing.com,
> darren(a)os.amperecomputing.com, crash-utility(a)redhat.com,
> lijiang(a)redhat.com, Huang Shijie <shijie(a)os.amperecomputing.com>
> Subject: [Crash-utility] [PATCH 1/2] Add a new helper arm64_get_pkd
> Message-ID: <20220318140937.3203595-1-shijie(a)os.amperecomputing.com>
> Content-Type: text/plain
>
> Use this new helper to get the pkd which
> may be used in future.
>
It seems to be an orphan patch? Could you please put this one into a
relevant patchset together? That may help me understand.
Thanks.
Lianbo
Also move struct proc_kcore_data to defs.h to
> avoid the compiler errors.
>
> Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
> ---
> defs.h | 16 ++++++++++++++++
> netdump.c | 5 +++++
> netdump.h | 12 ------------
> 3 files changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index 81ac049..4f06bdf 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -39,6 +39,7 @@
> #include <signal.h>
> #include <assert.h>
> #include <errno.h>
> +#include <elf.h>
> #include <dirent.h>
> #include <time.h>
> #include <zlib.h>
> @@ -6647,6 +6648,20 @@ int sparc64_vmalloc_addr(ulong);
> /*
> * netdump.c
> */
> +
> +struct proc_kcore_data {
> + uint flags;
> + uint segments;
> + char *elf_header;
> + size_t header_size;
> + Elf64_Phdr *load64;
> + Elf64_Phdr *notes64;
> + Elf32_Phdr *load32;
> + Elf32_Phdr *notes32;
> + void *vmcoreinfo;
> + uint size_vmcoreinfo;
> +};
> +
> int is_netdump(char *, ulong);
> uint netdump_page_size(void);
> int read_netdump(int, void *, int, ulong, physaddr_t);
> @@ -6689,6 +6704,7 @@ int kdump_phys_base(ulong *);
> int kdump_set_phys_base(ulong);
> int arm_kdump_phys_base(ulong *);
> int arm_kdump_phys_end(ulong *);
> +struct proc_kcore_data *arm64_get_pkd(void);
> int is_proc_kcore(char *, ulong);
> int proc_kcore_init(FILE *, int);
> int read_proc_kcore(int, void *, int, ulong, physaddr_t);
> diff --git a/netdump.c b/netdump.c
> index ff273b4..3066c80 100644
> --- a/netdump.c
> +++ b/netdump.c
> @@ -3864,6 +3864,11 @@ get_netdump_regs_arm64(struct bt_info *bt, ulong
> *eip, ulong *esp)
> machdep->get_stack_frame(bt, eip, esp);
> }
>
> +struct proc_kcore_data *arm64_get_pkd(void)
> +{
> + return pkd;
> +}
> +
> static void
> get_netdump_regs_mips(struct bt_info *bt, ulong *eip, ulong *esp)
> {
> diff --git a/netdump.h b/netdump.h
> index ffd60b8..119cb72 100644
> --- a/netdump.h
> +++ b/netdump.h
> @@ -148,15 +148,3 @@ struct vmcore_data {
>
> #define MAX_KCORE_ELF_HEADER_SIZE (32768)
>
> -struct proc_kcore_data {
> - uint flags;
> - uint segments;
> - char *elf_header;
> - size_t header_size;
> - Elf64_Phdr *load64;
> - Elf64_Phdr *notes64;
> - Elf32_Phdr *load32;
> - Elf32_Phdr *notes32;
> - void *vmcoreinfo;
> - uint size_vmcoreinfo;
> -};
> --
> 2.30.2
>
2 years, 5 months
[PATCH] kernel: fix start-up time degradation caused by strings command
by d.hatayama@fujitsu.com
verify_namelist() uses strings command and scans full part of vmlinux
file to find linux_banner string. However, vmlinux file is quite large
these days, reaching over 500MB. As a result, this degradates start-up
time of crash command 10 or more seconds. (Of course, this depends on
machines you use for investigation, but I guess typically we cannot
use such powerful machines to investigate crash dump...)
To resolve this issue, let's use bfd library and read linux_banner
string in vmlinux file directly.
A simple benchmark shows the following result:
Without the fix:
# cat ./commands.txt
quit
# time ./crash -i ./commands.txt \
/usr/lib/debug/lib/modules/5.16.15-201.fc35.x86_64/vmlinux \
/var/crash/*/vmcore >/dev/null 2>&1
real 0m20.251s
user 0m19.022s
sys 0m1.054s
With the fix:
# time ./crash -i ./commands.txt \
/usr/lib/debug/lib/modules/5.16.15-201.fc35.x86_64/vmlinux \
/var/crash/*/vmcore >/dev/null 2>&1
real 0m6.528s
user 0m6.143s
sys 0m0.431s
Note that this commit keeps the original logic that uses strings
command for backward compatibility for in case.
Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)fujitsu.com>
---
Makefile | 2 +-
kernel.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 007d030..e520b12 100644
--- a/Makefile
+++ b/Makefile
@@ -364,7 +364,7 @@ task.o: ${GENERIC_HFILES} task.c
${CC} -c ${CRASH_CFLAGS} task.c ${WARNING_OPTIONS} ${WARNING_ERROR}
kernel.o: ${GENERIC_HFILES} kernel.c
- ${CC} -c ${CRASH_CFLAGS} kernel.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+ ${CC} -c ${CRASH_CFLAGS} kernel.c -I${BFD_DIRECTORY} -I${GDB_INCLUDE_DIRECTORY} ${WARNING_OPTIONS} ${WARNING_ERROR}
printk.o: ${GENERIC_HFILES} printk.c
${CC} -c ${CRASH_CFLAGS} printk.c ${WARNING_OPTIONS} ${WARNING_ERROR}
diff --git a/kernel.c b/kernel.c
index 1c63447..92434a3 100644
--- a/kernel.c
+++ b/kernel.c
@@ -23,6 +23,11 @@
#include <ctype.h>
#include <stdbool.h>
#include "xendump.h"
+#if defined(GDB_7_6) || defined(GDB_10_2)
+#define __CONFIG_H__ 1
+#include "config.h"
+#endif
+#include "bfd.h"
static void do_module_cmd(ulong, char *, ulong, char *, char *);
static void show_module_taint(void);
@@ -97,6 +102,7 @@ static void dump_printk_safe_seq_buf(int);
static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
static int is_pvops_xen(void);
+static int get_linux_banner_from_vmlinux(char *, size_t);
/*
@@ -1324,6 +1330,12 @@ verify_namelist()
target_smp = strstr(kt->utsname.version, " SMP ") ? TRUE : FALSE;
namelist_smp = FALSE;
+ if (get_linux_banner_from_vmlinux(buffer, sizeof(buffer)) &&
+ strstr(buffer, kt->proc_version)) {
+ found = TRUE;
+ goto found;
+ }
+
sprintf(command, "/usr/bin/strings %s", namelist);
if ((pipe = popen(command, "r")) == NULL) {
error(INFO, "%s: %s\n", namelist, strerror(errno));
@@ -1384,6 +1396,7 @@ verify_namelist()
}
}
+found:
if (found) {
if (CRASHDEBUG(1)) {
fprintf(fp, "verify_namelist:\n");
@@ -11770,3 +11783,31 @@ check_vmcoreinfo(void)
}
}
}
+
+static
+int get_linux_banner_from_vmlinux(char *buf, size_t size)
+{
+ struct bfd_section *sect;
+ long offset;
+
+ sect = bfd_get_section_by_name(st->bfd, ".rodata");
+ if (!sect)
+ return FALSE;
+
+ /*
+ * Although symbol_value() returns dynamic symbol value that
+ * is affected by kaslr, which is different from static symbol
+ * value in vmlinux file, but relative offset to linux_banner
+ * object in .rodata section is idential.
+ */
+ offset = symbol_value("linux_banner") - symbol_value(".rodata");
+
+ if (!bfd_get_section_contents(st->bfd,
+ sect,
+ buf,
+ offset,
+ size))
+ return FALSE;
+
+ return TRUE;
+}
--
2.31.1
2 years, 5 months
Re: [Crash-utility] [PATCH 2/2] remote.c: Replace gethostbyname() with getaddrinfo()
by lijiang
Thank you for the patch, David.
On Fri, Mar 25, 2022 at 9:53 AM <crash-utility-request(a)redhat.com> wrote:
> Date: Thu, 24 Mar 2022 11:10:16 -0400
> From: David Cantrell <dcantrell(a)redhat.com>
> To: crash-utility(a)redhat.com
> Cc: David Cantrell <dcantrell(a)redhat.com>
> Subject: [Crash-utility] [PATCH 2/2] remote.c: Replace gethostbyname()
> with getaddrinfo()
> Message-ID: <20220324151016.202675-3-dcantrell(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Handle AF_INET6 in addition to AF_INET addresses. Use getaddrinfo()
> in place of gethostbyname() along with the other IPv6-capable
> networking functions. gethostbyname() is present in POSIX.1-2001 but
> was removed in POSIX.1-2008 recommending getaddrinfo() instead.
>
> Signed-off-by: David Cantrell <dcantrell(a)redhat.com>
> ---
> remote.c | 67 +++++++++++++++++++++++++++++++++++++-------------------
> 1 file changed, 45 insertions(+), 22 deletions(-)
>
> diff --git a/remote.c b/remote.c
> index 67d6f17..c9f73c2 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -71,9 +71,10 @@ struct remote_context *rc = &remote_context;
> int
> main(int argc, char **argv)
> {
> - int c, sockfd, newsockfd, clilen;
> + int c, hp, sockfd, newsockfd, clilen;
> struct sockaddr_in serv_addr, cli_addr;
> - struct hostent *hp;
> + struct addrinfo hints;
> + struct addrinfo *result;
> ushort tcp_port;
> char hostname[MAXHOSTNAMELEN];
>
> @@ -112,9 +113,18 @@ main(int argc, char **argv)
>
> console("hostname: %s\n", hostname);
>
> - if ((hp = gethostbyname(hostname)) == NULL) {
> - console("gethostbyname failed: %s\n", hstrerror(h_errno));
> - perror("gethostbyname");
> + memset(&hints, 0, sizeof(hints));
> + hints.ai_family = AF_UNSPEC;
> + hints.ai_socktype = SOCK_DGRAM;
>
I would suggest having the same socktype with the socket(xx, SOCK_STREAM),
although it doesn't affect the result.
In addition, I got the following warnings, could you please remove those
two unused variables from the remote.c?
$make warn
remote.c: In function ‘is_remote_daemon’:
remote.c:1935:32: warning: unused variable ‘ip’ [-Wunused-variable]
1935 | struct in_addr *ip;
| ^~
remote.c:1870:35: warning: unused variable ‘rp’ [-Wunused-variable]
1870 | struct addrinfo *result, *rp;
| ^~
Thanks.
Lianbo
+ hints.ai_flags = AI_PASSIVE;
> + hints.ai_protocol = 0;
> + hints.ai_canonname = NULL;
> + hints.ai_addr = NULL;
> + hints.ai_next = NULL;
> +
> + if ((hp = getaddrinfo(hostname, NULL, &hints, &result)) != 0) {
> + console("getaddinfo failed: %s\n", gai_strerror(hp));
> + perror("getaddrinfo");
> exit(1);
> }
>
> @@ -125,14 +135,15 @@ main(int argc, char **argv)
>
> console("<daemon %d initiated>\n", getpid());
>
> - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
> - exit(1);
> -
> BZERO((char *)&serv_addr, sizeof(serv_addr));
> serv_addr.sin_family = AF_INET;
> - BCOPY(hp->h_addr, (char *)&serv_addr.sin_addr, hp->h_length);
> serv_addr.sin_port = htons(tcp_port);
> + BCOPY(result->ai_addr, (char *)&serv_addr.sin_addr,
> result->ai_addrlen);
> +
> + if ((sockfd = socket(result->ai_family, SOCK_STREAM, 0)) < 0)
> + exit(1);
>
> + freeaddrinfo(result);
> daemon_socket_options(sockfd);
>
> if (bind(sockfd, (struct sockaddr *)&serv_addr,
> sizeof(serv_addr)) < 0){
> @@ -1854,7 +1865,9 @@ is_remote_daemon(char *dp)
> char sendbuf[BUFSIZE];
> char recvbuf[BUFSIZE];
> char *portp, *filep, *file1, *file2;
> - struct hostent *hp;
> + int hp;
> + struct addrinfo hints;
> + struct addrinfo *result, *rp;
> struct sockaddr_in serv_addr;
> char addrbuf[INET_ADDRSTRLEN];
>
> @@ -1904,18 +1917,27 @@ is_remote_daemon(char *dp)
> fprintf(fp, " file2: [%s]\n", file2);
> }
>
> - if ((hp = gethostbyname(pc->server)) == NULL) {
> + memset(&hints, 0, sizeof(hints));
> + hints.ai_family = AF_UNSPEC;
> + hints.ai_socktype = SOCK_DGRAM;
>
Ditto.
> + hints.ai_flags = AI_PASSIVE;
> + hints.ai_protocol = 0;
> + hints.ai_canonname = NULL;
> + hints.ai_addr = NULL;
> + hints.ai_next = NULL;
> +
> + if ((hp = getaddrinfo(pc->server, NULL, &hints, &result)) != 0) {
> herror(pc->server);
> - error(FATAL, "gethostbyname [%s] failed\n", pc->server);
> + error(FATAL, "getaddrinfo [%s] failed: %s\n", pc->server,
> gai_strerror(hp));
> }
>
> if (CRASHDEBUG(1)) {
> - struct in_addr *ip;
> - char **listptr;
> + struct in_addr *ip;
> + struct addrinfo *listptr;
>
> - listptr = hp->h_addr_list;
> - while ((ip = (struct in_addr *) *listptr++) != NULL)
> - printf("%s\n", inet_ntop(AF_INET, ip, addrbuf,
> INET_ADDRSTRLEN));
> + listptr = result;
> + for (listptr = result; listptr != NULL; listptr =
> listptr->ai_next)
> + printf("%s\n", inet_ntop(listptr->ai_family,
> listptr->ai_addr, addrbuf, INET_ADDRSTRLEN));
> }
>
> if ((pc->sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
> @@ -1924,20 +1946,21 @@ is_remote_daemon(char *dp)
> }
>
> BZERO((char *)&serv_addr, sizeof(struct sockaddr_in));
> - serv_addr.sin_family = AF_INET;
> - BCOPY(hp->h_addr, (char *)&serv_addr.sin_addr, hp->h_length);
> + serv_addr.sin_family = result->ai_family;
> + BCOPY(result->ai_addr, &serv_addr.sin_addr, result->ai_addrlen);
> serv_addr.sin_port = htons(pc->port);
>
> if (connect(pc->sockfd, (struct sockaddr *)&serv_addr,
> sizeof(struct sockaddr_in)) < 0) {
> - herror(hp->h_name);
> - error(FATAL, "connect [%s:%d] failed\n", hp->h_name,
> pc->port);
> + herror(pc->server);
> + error(FATAL, "connect [%s:%d] failed\n", pc->server,
> pc->port);
> clean_exit(1);
> }
>
> if (CRASHDEBUG(1))
> - printf("connect [%s:%d]: success\n", hp->h_name, pc->port);
> + printf("connect [%s:%d]: success\n", pc->server, pc->port);
>
> + freeaddrinfo(result);
> remote_socket_options(pc->sockfd);
>
> /*
> --
> 2.35.1
>
2 years, 5 months