package init

This commit is contained in:
chengquan 2019-12-26 15:15:03 +08:00
parent 658ea4ff0c
commit 58e33e2011
58 changed files with 6891 additions and 75 deletions

4
98-kexec.rules Normal file
View File

@ -0,0 +1,4 @@
SUBSYSTEM=="cpu", ACTION=="add", PROGRAM="/bin/systemctl try-restart kdump.service"
SUBSYSTEM=="cpu", ACTION=="remove", PROGRAM="/bin/systemctl try-restart kdump.service"
SUBSYSTEM=="memory", ACTION=="online", PROGRAM="/bin/systemctl try-restart kdump.service"
SUBSYSTEM=="memory", ACTION=="offline", PROGRAM="/bin/systemctl try-restart kdump.service"

View File

@ -1,36 +0,0 @@
# kexec-tools
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +0,0 @@
# kexec-tools
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -0,0 +1,29 @@
From 776d8f6355fdf77ec63bae4be09b8f40d0c831ad Mon Sep 17 00:00:00 2001
From: pengyeqing <pengyeqing@huawei.com>
Date: Sun, 18 Aug 2019 23:59:23 +0000
Subject: [PATCH] kexec-tools: add secure compile options for makedumpfile
reason:add secure compile options for makedumpfile
Signed-off-by: pengyeqing <pengyeqing@huawei.com>
---
Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/makedumpfile-1.6.4/Makefile b/makedumpfile-1.6.4/Makefile
index 612b9d0..180a64f 100644
--- a/makedumpfile-1.6.4/Makefile
+++ b/makedumpfile-1.6.4/Makefile
@@ -10,7 +10,8 @@ endif
CFLAGS = -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \
-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
- -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"'
+ -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' \
+ -fstack-protector-strong -Wl,-z,now
CFLAGS_ARCH = -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \
-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
# LDFLAGS = -L/usr/local/lib -I/usr/local/include
--
1.8.3.1

View File

@ -0,0 +1,40 @@
From ca4823aa2fc28e00400e65473caeede5cadd0da0 Mon Sep 17 00:00:00 2001
From: Munehisa Kamata <kamatam@amazon.com>
Date: Tue, 26 Jun 2018 12:47:29 -0700
Subject: [PATCH 13/37] arm64: error out if kernel command line is too long
Currently, in arm64, kexec silently truncates kernel command line longer
than COMMAND_LINE_SIZE - 1. Error out in that case as some other
architectures already do that. The error message is copied from x86_64.
Suggested-by: Tom Kirchner <tjk@amazon.com>
Signed-off-by: Munehisa Kamata <kamatam@amazon.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index a206c17..7a12479 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -598,8 +598,15 @@ int arm64_load_other_segments(struct kexec_info *info,
char command_line[COMMAND_LINE_SIZE] = "";
if (arm64_opts.command_line) {
+ if (strlen(arm64_opts.command_line) >
+ sizeof(command_line) - 1) {
+ fprintf(stderr,
+ "Kernel command line too long for kernel!\n");
+ return EFAILED;
+ }
+
strncpy(command_line, arm64_opts.command_line,
- sizeof(command_line));
+ sizeof(command_line) - 1);
command_line[sizeof(command_line) - 1] = 0;
}
--
2.6.4.windows.1

View File

@ -0,0 +1,278 @@
From 6633170a04b1fc55eb72adc0150ffcd1b85be8ce Mon Sep 17 00:00:00 2001
From: Chen Zhou <chenzhou10@huawei.com>
Date: Fri, 29 Mar 2019 21:01:29 +0800
Subject: [PATCH] kexec-tools: support more than one crash kernel regions
reason: When crashkernel is reserved above 4G in memory, kernel should
reserve some amount of low memory for swiotlb and some DMA buffers.
So there may be two crash kernel regions, one is below 4G, the other
is above 4G.
Currently, there is only one crash kernel region on arm64, and pass
"linux,usable-memory-range = <BASE SIZE>" property to crash dump
kernel. Now, we pass
"linux,usable-memory-range = <BASE1 SIZE1 BASE2 SIZE2>" to crash
dump kernel to support two crash kernel regions and load crash
kernel high.
This patch paves the way for the use of arm64 reserving crashkernel
above 4G. The details are as below:
Link: https://lore.kernel.org/linux-arm-kernel/20190403030546.23718-1-chenzhou10@huawei.com/T/#t
Signed-off-by: Chen Zhou <chenzhou10@huawei.com>
---
kexec/arch/arm64/crashdump-arm64.c | 44 +++++++++++++++++------------
kexec/arch/arm64/crashdump-arm64.h | 3 +-
kexec/arch/arm64/kexec-arm64.c | 57 +++++++++++++++++++++++++++++---------
3 files changed, 72 insertions(+), 32 deletions(-)
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 4fd7aa8..158e778 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -32,11 +32,11 @@ static struct memory_ranges system_memory_rgns = {
};
/* memory range reserved for crashkernel */
-struct memory_range crash_reserved_mem;
+struct memory_range crash_reserved_mem[CRASH_MAX_RESERVED_RANGES];
struct memory_ranges usablemem_rgns = {
.size = 0,
- .max_size = 1,
- .ranges = &crash_reserved_mem,
+ .max_size = CRASH_MAX_RESERVED_RANGES,
+ .ranges = crash_reserved_mem,
};
struct memory_range elfcorehdr_mem;
@@ -108,7 +108,7 @@ int is_crashkernel_mem_reserved(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
- return crash_reserved_mem.start != crash_reserved_mem.end;
+ return usablemem_rgns.size;
}
/*
@@ -122,6 +122,8 @@ int is_crashkernel_mem_reserved(void)
*/
static int crash_get_memory_ranges(void)
{
+ int i;
+
/*
* First read all memory regions that can be considered as
* system memory including the crash area.
@@ -129,16 +131,19 @@ static int crash_get_memory_ranges(void)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
- /* allow only a single region for crash dump kernel */
- if (usablemem_rgns.size != 1)
+ /* allow one or two region for crash dump kernel */
+ if (!usablemem_rgns.size)
return -EINVAL;
- dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
+ dbgprint_mem_range("Reserved memory range",
+ usablemem_rgns.ranges, usablemem_rgns.size);
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
- fprintf(stderr,
- "Error: Number of crash memory ranges excedeed the max limit\n");
- return -ENOMEM;
+ for (i = 0; i < usablemem_rgns.size; i++) {
+ if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem[i])) {
+ fprintf(stderr,
+ "Error: Number of crash memory ranges excedeed the max limit\n");
+ return -ENOMEM;
+ }
}
/*
@@ -199,7 +204,8 @@ int load_crashdump_segments(struct kexec_info *info)
return EFAILED;
elfcorehdr = add_buffer_phys_virt(info, buf, bufsz, bufsz, 0,
- crash_reserved_mem.start, crash_reserved_mem.end,
+ crash_reserved_mem[usablemem_rgns.size - 1].start,
+ crash_reserved_mem[usablemem_rgns.size - 1].end,
-1, 0);
elfcorehdr_mem.start = elfcorehdr;
@@ -217,21 +223,23 @@ int load_crashdump_segments(struct kexec_info *info)
* virt_to_phys() in add_segment().
* So let's fix up those values for later use so the memory base
* (arm64_mm.phys_offset) will be correctly replaced with
- * crash_reserved_mem.start.
+ * crash_reserved_mem[usablemem_rgns.size - 1].start.
*/
void fixup_elf_addrs(struct mem_ehdr *ehdr)
{
struct mem_phdr *phdr;
int i;
- ehdr->e_entry += - arm64_mem.phys_offset + crash_reserved_mem.start;
+ ehdr->e_entry += -arm64_mem.phys_offset +
+ crash_reserved_mem[usablemem_rgns.size - 1].start;
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &ehdr->e_phdr[i];
if (phdr->p_type != PT_LOAD)
continue;
phdr->p_paddr +=
- (-arm64_mem.phys_offset + crash_reserved_mem.start);
+ (-arm64_mem.phys_offset +
+ crash_reserved_mem[usablemem_rgns.size - 1].start);
}
}
@@ -240,11 +248,11 @@ int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
if (!usablemem_rgns.size)
kexec_iomem_for_each_line(NULL, iomem_range_callback, NULL);
- if (!crash_reserved_mem.end)
+ if (!usablemem_rgns.size)
return -1;
- *start = crash_reserved_mem.start;
- *end = crash_reserved_mem.end;
+ *start = crash_reserved_mem[usablemem_rgns.size - 1].start;
+ *end = crash_reserved_mem[usablemem_rgns.size - 1].end;
return 0;
}
diff --git a/kexec/arch/arm64/crashdump-arm64.h b/kexec/arch/arm64/crashdump-arm64.h
index 880b83a..c07233f 100644
--- a/kexec/arch/arm64/crashdump-arm64.h
+++ b/kexec/arch/arm64/crashdump-arm64.h
@@ -15,9 +15,10 @@
#include "kexec.h"
#define CRASH_MAX_MEMORY_RANGES 32
+#define CRASH_MAX_RESERVED_RANGES 8
extern struct memory_ranges usablemem_rgns;
-extern struct memory_range crash_reserved_mem;
+extern struct memory_range crash_reserved_mem[];
extern struct memory_range elfcorehdr_mem;
extern int load_crashdump_segments(struct kexec_info *info);
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 2992bce..2bf8b66 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -414,6 +414,34 @@ static int fdt_setprop_range(void *fdt, int nodeoffset,
return result;
}
+static int fdt_setprop_ranges(void *fdt, int nodeoffset,
+ const char *name, struct memory_ranges *ranges,
+ uint32_t address_cells, uint32_t size_cells)
+{
+ void *buf, *prop;
+ size_t buf_size;
+ int i, result;
+
+ buf_size = (address_cells + size_cells) * sizeof(uint32_t) *
+ ranges->size;
+ prop = buf = xmalloc(buf_size);
+
+ for (i = 0; i < ranges->size; i++) {
+ fill_property(prop, ranges->ranges[i].start, address_cells);
+ prop += address_cells * sizeof(uint32_t);
+
+ fill_property(prop, ranges->ranges[i].end -
+ ranges->ranges[i].start + 1, size_cells);
+ prop += size_cells * sizeof(uint32_t);
+ }
+
+ result = fdt_setprop(fdt, nodeoffset, name, buf, buf_size);
+
+ free(buf);
+
+ return result;
+}
+
/**
* setup_2nd_dtb - Setup the 2nd stage kernel's dtb.
*/
@@ -427,7 +455,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
int nodeoffset;
char *new_buf = NULL;
int new_size;
- int result;
+ int i, result;
result = fdt_check_header(dtb->buf);
@@ -430,19 +430,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
goto on_error;
}
- if (!cells_size_fitted(address_cells, size_cells,
- &crash_reserved_mem)) {
- fprintf(stderr,
- "kexec: usable memory range doesn't fit cells-size.\n");
- result = -EINVAL;
- goto on_error;
- }
+ for (i = 0; i < usablemem_rgns.size; i++) {
+ if (!cells_size_fitted(address_cells, size_cells,
+ &crash_reserved_mem[i])) {
+ fprintf(stderr,
+ "kexec: usable memory range doesn't fit cells-size.\n");
+ result = -EINVAL;
+ goto on_error;
+ }
+ }
/* duplicate dt blob */
range_len = sizeof(uint32_t) * (address_cells + size_cells);
new_size = fdt_totalsize(dtb->buf)
+ fdt_prop_len(PROP_ELFCOREHDR, range_len)
- + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len);
+ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size);
new_buf = xmalloc(new_size);
result = fdt_open_into(dtb->buf, new_buf, new_size);
@@ -565,8 +596,8 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
/* add linux,usable-memory-range */
nodeoffset = fdt_path_offset(new_buf, "/chosen");
- result = fdt_setprop_range(new_buf, nodeoffset,
- PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
+ result = fdt_setprop_ranges(new_buf, nodeoffset,
+ PROP_USABLE_MEM_RANGE, &usablemem_rgns,
address_cells, size_cells);
if (result) {
dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
@@ -599,13 +630,13 @@ unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
if (info->kexec_flags & KEXEC_ON_CRASH) {
unsigned long hole_end;
- hole = (crash_reserved_mem.start < mem_min ?
- mem_min : crash_reserved_mem.start);
+ hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ?
+ mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start);
hole = _ALIGN_UP(hole, MiB(2));
hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
if ((hole_end > mem_max) ||
- (hole_end > crash_reserved_mem.end)) {
+ (hole_end > crash_reserved_mem[usablemem_rgns.size - 1].end)) {
dbgprintf("%s: Crash kernel out of range\n", __func__);
hole = ULONG_MAX;
}
@@ -673,7 +704,7 @@ int arm64_load_other_segments(struct kexec_info *info,
hole_min = image_base + arm64_mem.image_size;
if (info->kexec_flags & KEXEC_ON_CRASH)
- hole_max = crash_reserved_mem.end;
+ hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
else
hole_max = ULONG_MAX;
--
2.7.4

View File

@ -0,0 +1,75 @@
From f1f2f9edf8d4c5294e30f20546c5177ab59e53a2 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Date: Fri, 1 Feb 2019 15:50:28 +0000
Subject: [PATCH 33/37] arm64: wipe old initrd addresses when patching the DTB
When copying the DTB from the current kernel, if the user didn't pass an
initrd on the command-line, make sure that the new DTB doesn't contain
initrd properties with stale addresses. Otherwise the next kernel will
try to unpack the initramfs from a location that contains junk, since
the initial initrd is long gone:
[ 49.370026] Initramfs unpacking failed: junk in compressed archive
This issue used to be hidden by a successful recovery, but since commit
ff1522bb7d98 ("initramfs: cleanup incomplete rootfs") in Linux, the
kernel removes the default /root mountpoint after failing to load an
initramfs, and cannot mount the rootfs passed on the command-line
anymore.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.c | 5 +++++
kexec/dt-ops.c | 6 ++++++
kexec/dt-ops.h | 1 +
3 files changed, 12 insertions(+)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 1cde75d..2992bce 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -713,6 +713,11 @@ int arm64_load_other_segments(struct kexec_info *info,
}
}
+ if (!initrd_buf) {
+ /* Don't reuse the initrd addresses from 1st DTB */
+ dtb_clear_initrd((char **)&dtb.buf, &dtb.size);
+ }
+
/* Check size limit as specified in booting.txt. */
if (dtb.size > MiB(2)) {
diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c
index 5626c47..dd2feaa 100644
--- a/kexec/dt-ops.c
+++ b/kexec/dt-ops.c
@@ -45,6 +45,12 @@ int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end)
return 0;
}
+void dtb_clear_initrd(char **dtb, off_t *dtb_size)
+{
+ dtb_delete_property(*dtb, n_chosen, p_initrd_start);
+ dtb_delete_property(*dtb, n_chosen, p_initrd_end);
+}
+
int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line)
{
return dtb_set_property(dtb, dtb_size, n_chosen, p_bootargs,
diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h
index e70d15d..03659ce 100644
--- a/kexec/dt-ops.h
+++ b/kexec/dt-ops.h
@@ -4,6 +4,7 @@
#include <sys/types.h>
int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end);
+void dtb_clear_initrd(char **dtb, off_t *dtb_size);
int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line);
int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
const char *prop, const void *value, int value_len);
--
2.6.4.windows.1

View File

@ -0,0 +1,37 @@
From daa57a0d1aa31fad5811ba70d37e1ed23773151e Mon Sep 17 00:00:00 2001
From: kangenbo <kangenbo@huawei.com>
Date: Wed, 30 Jan 2019 15:50:31 +0800
Subject: [PATCH] kexec-tools: get the paddr of mem_section return error address
reason: get the paddr of mem_section return error address
Signed-off-by: kangenbo <kangenbo@huawei.com>
---
makedumpfile-1.6.4/arch/arm64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/makedumpfile-1.6.4/arch/arm64.c b/makedumpfile-1.6.4/arch/arm64.c
index 2fd3e18..cc59e63 100644
--- a/makedumpfile-1.6.4/arch/arm64.c
+++ b/makedumpfile-1.6.4/arch/arm64.c
@@ -336,7 +336,7 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
if ((pud_val(pudv) & PUD_TYPE_MASK) == PUD_TYPE_SECT) {
/* 1GB section for Page Table level = 4 and Page Size = 4KB */
- paddr = (pud_val(pudv) & (PUD_MASK & PMD_SECTION_MASK))
+ paddr = (pud_val(pudv) & (PUD_MASK & PHYS_MASK))
+ (vaddr & (PUD_SIZE - 1));
return paddr;
}
@@ -367,7 +367,7 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
break;
case PMD_TYPE_SECT:
/* 512MB section for Page Table level = 3 and Page Size = 64KB*/
- paddr = (pmd_val(pmdv) & (PMD_MASK & PMD_SECTION_MASK))
+ paddr = (pmd_val(pmdv) & (PMD_MASK & PHYS_MASK))
+ (vaddr & (PMD_SIZE - 1));
break;
}
--
1.7.12.4

View File

@ -0,0 +1,44 @@
#!/bin/bash
. /etc/sysconfig/kdump
. /lib/kdump/kdump-lib.sh
KDUMP_KERNEL=""
KDUMP_INITRD=""
check() {
if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]\
|| [ -n "${IN_KDUMP}" ]
then
return 1
fi
return 255
}
depends() {
echo "base shutdown"
return 0
}
prepare_kernel_initrd() {
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
if [ -z "$KDUMP_KERNELVER" ]; then
kdump_kver=`uname -r`
else
kdump_kver=$KDUMP_KERNELVER
fi
KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
}
install() {
inst_multiple tail find cut dirname hexdump
inst_simple "/etc/sysconfig/kdump"
inst_binary "/usr/sbin/kexec"
inst_binary "/usr/bin/gawk" "/usr/bin/awk"
inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
inst_hook cmdline 00 "$moddir/early-kdump.sh"
prepare_kernel_initrd
inst_binary "$KDUMP_KERNEL"
inst_binary "$KDUMP_INITRD"
}

84
dracut-early-kdump.sh Normal file
View File

@ -0,0 +1,84 @@
#! /bin/sh
KEXEC=/sbin/kexec
standard_kexec_args="-p"
EARLY_KDUMP_INITRD=""
EARLY_KDUMP_KERNEL=""
EARLY_KDUMP_CMDLINE=""
EARLY_KDUMP_KERNELVER=""
EARLY_KEXEC_ARGS=""
. /etc/sysconfig/kdump
. /lib/dracut-lib.sh
. /lib/kdump-lib.sh
prepare_parameters()
{
EARLY_KDUMP_CMDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}")
KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
#make early-kdump kernel string
if [ -z "$KDUMP_KERNELVER" ]; then
EARLY_KDUMP_KERNELVER=`uname -r`
else
EARLY_KDUMP_KERNELVER=$KDUMP_KERNELVER
fi
EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
#make early-kdump initrd string
EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img"
}
early_kdump_load()
{
check_kdump_feasibility
if [ $? -ne 0 ]; then
return 1
fi
if is_fadump_capable; then
echo "WARNING: early kdump doesn't support fadump."
return 1
fi
check_current_kdump_status
if [ $? == 0 ]; then
return 1
fi
prepare_parameters
EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}")
if is_secure_boot_enforced; then
echo "Secure Boot is enabled. Using kexec file based syscall."
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
fi
$KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \
--command-line="$EARLY_KDUMP_CMDLINE" \
--initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL
if [ $? == 0 ]; then
echo "kexec: loaded early-kdump kernel"
return 0
else
echo "kexec: failed to load early-kdump kernel"
return 1
fi
}
set_early_kdump()
{
if getargbool 0 rd.earlykdump; then
echo "early-kdump is enabled."
early_kdump_load
else
echo "early-kdump is disabled."
fi
return 0
}
set_early_kdump

View File

@ -0,0 +1,30 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Kdump Vmcore Save Service
After=initrd.target initrd-parse-etc.service sysroot.mount
After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dracut-pre-pivot.service
Before=initrd-cleanup.service
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureIsolate=yes
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=/bin/kdump.sh
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP

View File

@ -0,0 +1,28 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will be placed in kdump initramfs and replace both the systemd
# emergency service and dracut emergency shell. IOW, any emergency will be
# kick this service and in turn isolating to kdump error handler.
[Unit]
Description=Kdump Emergency
DefaultDependencies=no
IgnoreOnIsolate=yes
[Service]
ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP

View File

@ -0,0 +1,14 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Emergency Mode
Documentation=man:systemd.special(7)
Requires=emergency.service
After=emergency.service
AllowIsolate=yes
IgnoreOnIsolate=yes

View File

@ -0,0 +1,34 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will run the real kdump error handler code. Executing the
# default action configured in kdump.conf
[Unit]
Description=Kdump Error Handler
DefaultDependencies=no
After=systemd-vconsole-setup.service
Wants=systemd-vconsole-setup.service
AllowIsolate=yes
[Service]
Environment=HOME=/
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
WorkingDirectory=/
ExecStart=/bin/kdump-error-handler.sh
ExecStopPost=-/usr/bin/systemctl --fail --no-block default
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP

View File

@ -0,0 +1,10 @@
#!/bin/sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
export PATH=$PATH:$KDUMP_SCRIPT_DIR
get_kdump_confs
do_default_action
do_final_action

204
dracut-kdump.sh Normal file
View File

@ -0,0 +1,204 @@
#!/bin/sh
# continue here only if we have to save dump.
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ]; then
exit 0
fi
exec &> /dev/console
. /lib/dracut-lib.sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
DUMP_RETVAL=0
export PATH=$PATH:$KDUMP_SCRIPT_DIR
do_dump()
{
local _ret
eval $DUMP_INSTRUCTION
_ret=$?
if [ $_ret -ne 0 ]; then
echo "kdump: saving vmcore failed"
fi
return $_ret
}
do_kdump_pre()
{
if [ -n "$KDUMP_PRE" ]; then
"$KDUMP_PRE"
fi
}
do_kdump_post()
{
if [ -n "$KDUMP_POST" ]; then
"$KDUMP_POST" "$1"
fi
}
add_dump_code()
{
DUMP_INSTRUCTION=$1
}
dump_raw()
{
local _raw=$1
[ -b "$_raw" ] || return 1
echo "kdump: saving to raw disk $_raw"
if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
_src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
_src_size_mb=$(($_src_size / 1048576))
monitor_dd_progress $_src_size_mb &
fi
echo "kdump: saving vmcore"
$CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
sync
echo "kdump: saving vmcore complete"
return 0
}
dump_ssh()
{
local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
local _host=$2
echo "kdump: saving to $_host:$_dir"
cat /var/lib/random-seed > /dev/urandom
ssh -q $_opt $_host mkdir -p $_dir || return 1
save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
echo "kdump: saving vmcore"
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" || return 1
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore" || return 1
else
$CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "dd bs=512 of=$_dir/vmcore-incomplete" || return 1
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore.flat" || return 1
fi
echo "kdump: saving vmcore complete"
return 0
}
save_vmcore_dmesg_ssh() {
local _dmesg_collector=$1
local _path=$2
local _opts="$3"
local _location=$4
echo "kdump: saving vmcore-dmesg.txt"
$_dmesg_collector /proc/vmcore | ssh $_opts $_location "dd of=$_path/vmcore-dmesg-incomplete.txt"
_exitcode=$?
if [ $_exitcode -eq 0 ]; then
ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
echo "kdump: saving vmcore-dmesg.txt complete"
else
echo "kdump: saving vmcore-dmesg.txt failed"
fi
}
get_host_ip()
{
local _host
if is_nfs_dump_target || is_ssh_dump_target
then
kdumpnic=$(getarg kdumpnic=)
[ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1
_host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
[ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
_host=`echo $_host | head -n 1 | cut -d' ' -f2`
_host="${_host%%/*}"
[ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
HOST_IP=$_host
fi
return 0
}
read_kdump_conf()
{
if [ ! -f "$KDUMP_CONF" ]; then
echo "kdump: $KDUMP_CONF not found"
return
fi
get_kdump_confs
# rescan for add code for dump target
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
config_val=$(strip_comments $config_val)
case "$config_opt" in
dracut_args)
config_val=$(get_dracut_args_target "$config_val")
[ -n "$config_val" ] && add_dump_code "dump_fs $config_val"
;;
ext[234]|xfs|btrfs|minix|nfs)
add_dump_code "dump_fs $config_val"
;;
raw)
add_dump_code "dump_raw $config_val"
;;
ssh)
add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val"
;;
esac
done < $KDUMP_CONF
}
fence_kdump_notify()
{
if [ -n "$FENCE_KDUMP_NODES" ]; then
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
fi
}
read_kdump_conf
fence_kdump_notify
get_host_ip
if [ $? -ne 0 ]; then
echo "kdump: get_host_ip exited with non-zero status!"
exit 1
fi
if [ -z "$DUMP_INSTRUCTION" ]; then
add_dump_code "dump_fs $NEWROOT"
fi
do_kdump_pre
if [ $? -ne 0 ]; then
echo "kdump: kdump_pre script exited with non-zero status!"
do_final_action
fi
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
do_dump
DUMP_RETVAL=$?
do_kdump_post $DUMP_RETVAL
if [ $? -ne 0 ]; then
echo "kdump: kdump_post script exited with non-zero status!"
fi
if [ $DUMP_RETVAL -ne 0 ]; then
exit 1
fi
do_final_action

771
dracut-module-setup.sh Normal file
View File

@ -0,0 +1,771 @@
#!/bin/bash
. $dracutfunctions
. /lib/kdump/kdump-lib.sh
if ! [[ -d "${initdir}/tmp" ]]; then
mkdir -p "${initdir}/tmp"
fi
check() {
[[ $debug ]] && set -x
#kdumpctl sets this explicitly
if [ -z "$IN_KDUMP" ] || [ ! -f /etc/kdump.conf ]
then
return 1
fi
return 0
}
depends() {
local _dep="base shutdown"
if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then
_dep="$_dep drm"
fi
if is_generic_fence_kdump -o is_pcs_fence_kdump; then
_dep="$_dep network"
fi
echo $_dep
return 0
}
kdump_get_persistent_dev() {
local dev="${1//\"/}"
case "$dev" in
UUID=*)
dev=`blkid -U "${dev#UUID=}"`
;;
LABEL=*)
dev=`blkid -L "${dev#LABEL=}"`
;;
esac
echo $(get_persistent_dev "$dev")
}
kdump_is_bridge() {
[ -d /sys/class/net/"$1"/bridge ]
}
kdump_is_bond() {
[ -d /sys/class/net/"$1"/bonding ]
}
kdump_is_team() {
[ -f /usr/bin/teamnl ] && teamnl $1 ports &> /dev/null
}
kdump_is_vlan() {
[ -f /proc/net/vlan/"$1" ]
}
# $1: netdev name
source_ifcfg_file() {
local ifcfg_file
ifcfg_file=$(get_ifcfg_filename $1)
if [ -f "${ifcfg_file}" ]; then
. ${ifcfg_file}
else
dwarning "The ifcfg file of $1 is not found!"
fi
}
# $1: netdev name
kdump_setup_dns() {
local _nameserver _dns
local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
source_ifcfg_file $1
[ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile"
[ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile"
while read content;
do
_nameserver=$(echo $content | grep ^nameserver)
[ -z "$_nameserver" ] && continue
_dns=$(echo $_nameserver | cut -d' ' -f2)
[ -z "$_dns" ] && continue
if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then
echo "nameserver=$_dns" >> "$_dnsfile"
fi
done < "/etc/resolv.conf"
}
#$1: netdev name
#$2: srcaddr
#if it use static ip echo it, or echo null
kdump_static_ip() {
local _netdev="$1" _srcaddr="$2" _ipv6_flag
local _netmask _gateway _ipaddr _target _nexthop
_ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
if is_ipv6_address $_srcaddr; then
_ipv6_flag="-6"
fi
if [ -n "$_ipaddr" ]; then
_gateway=$(ip $_ipv6_flag route list dev $_netdev | \
awk '/^default /{print $3}' | head -n 1)
if [ "x" != "x"$_ipv6_flag ]; then
# _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/"
_netmask=${_ipaddr#*\/}
_srcaddr="[$_srcaddr]"
_gateway="[$_gateway]"
else
_netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
fi
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
fi
/sbin/ip $_ipv6_flag route show | grep -v default | grep ".*via.* $_netdev " |\
while read _route; do
_target=`echo $_route | cut -d ' ' -f1`
_nexthop=`echo $_route | cut -d ' ' -f3`
if [ "x" != "x"$_ipv6_flag ]; then
_target="[$_target]"
_nexthop="[$_nexthop]"
fi
echo "rd.route=$_target:$_nexthop:$_netdev"
done >> ${initdir}/etc/cmdline.d/45route-static.conf
}
kdump_get_mac_addr() {
cat /sys/class/net/$1/address
}
#Bonding or team master modifies the mac address
#of its slaves, we should use perm address
kdump_get_perm_addr() {
local addr=$(ethtool -P $1 | sed -e 's/Permanent address: //')
if [ -z "$addr" ] || [ "$addr" = "00:00:00:00:00:00" ]
then
derror "Can't get the permanent address of $1"
else
echo "$addr"
fi
}
# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0
# Because kernel assigned names are not persistent between 1st and 2nd
# kernel. We could probably end up with eth0 being eth1, eth0 being
# eth1, and naming conflict happens.
kdump_setup_ifname() {
local _ifname
# If ifname already has 'kdump-' prefix, we must be switching from
# fadump to kdump. Skip prefixing 'kdump-' in this case as adding
# another prefix may truncate the ifname. Since an ifname with
# 'kdump-' is already persistent, this should be fine.
if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
_ifname="kdump-$1"
else
_ifname="$1"
fi
echo "$_ifname"
}
kdump_setup_bridge() {
local _netdev=$1
local _brif _dev _mac _kdumpdev
for _dev in `ls /sys/class/net/$_netdev/brif/`; do
_kdumpdev=$_dev
if kdump_is_bond "$_dev"; then
kdump_setup_bond "$_dev"
elif kdump_is_team "$_dev"; then
kdump_setup_team "$_dev"
elif kdump_is_vlan "$_dev"; then
kdump_setup_vlan "$_dev"
else
_mac=$(kdump_get_mac_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/41bridge.conf
fi
_brif+="$_kdumpdev,"
done
echo " bridge=$_netdev:$(echo $_brif | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/41bridge.conf
}
kdump_setup_bond() {
local _netdev=$1
local _dev _mac _slaves _kdumpdev
for _dev in `cat /sys/class/net/$_netdev/bonding/slaves`; do
_mac=$(kdump_get_perm_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/42bond.conf
_slaves+="$_kdumpdev,"
done
echo -n " bond=$_netdev:$(echo $_slaves | sed 's/,$//')" >> ${initdir}/etc/cmdline.d/42bond.conf
# Get bond options specified in ifcfg
source_ifcfg_file $_netdev
bondoptions="$(echo :$BONDING_OPTS | sed 's/\s\+/,/')"
echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf
}
kdump_setup_team() {
local _netdev=$1
local _dev _mac _slaves _kdumpdev
for _dev in `teamnl $_netdev ports | awk -F':' '{print $2}'`; do
_mac=$(kdump_get_perm_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/44team.conf
_slaves+="$_kdumpdev,"
done
echo " team=$_netdev:$(echo $_slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf
#Buggy version teamdctl outputs to stderr!
#Try to use the latest version of teamd.
teamdctl "$_netdev" config dump > ${initdir}/tmp/$$-$_netdev.conf
if [ $? -ne 0 ]
then
derror "teamdctl failed."
exit 1
fi
inst_dir /etc/teamd
inst_simple ${initdir}/tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf"
rm -f ${initdir}/tmp/$$-$_netdev.conf
}
kdump_setup_vlan() {
local _netdev=$1
local _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
local _netmac="$(kdump_get_mac_addr $_phydev)"
local _kdumpdev
#Just support vlan over bond, it is not easy
#to support all other complex setup
if kdump_is_bridge "$_phydev"; then
derror "Vlan over bridge is not supported!"
exit 1
elif kdump_is_team "$_phydev"; then
derror "Vlan over team is not supported!"
exit 1
elif kdump_is_bond "$_phydev"; then
kdump_setup_bond "$_phydev"
echo " vlan=$_netdev:$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf
else
_kdumpdev="$(kdump_setup_ifname $_phydev)"
echo " vlan=$_netdev:$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf
fi
}
# setup s390 znet cmdline
# $1: netdev name
kdump_setup_znet() {
local _options=""
source_ifcfg_file $1
for i in $OPTIONS; do
_options=${_options},$i
done
echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} > ${initdir}/etc/cmdline.d/30znet.conf
}
# Setup dracut to bringup a given network interface
kdump_setup_netdev() {
local _netdev=$1 _srcaddr=$2
local _static _proto _ip_conf _ip_opts _ifname_opts
local _netmac=$(kdump_get_mac_addr $_netdev)
if [ "$(uname -m)" = "s390x" ]; then
kdump_setup_znet $_netdev
fi
_static=$(kdump_static_ip $_netdev $_srcaddr)
if [ -n "$_static" ]; then
_proto=none
elif is_ipv6_address $_srcaddr; then
_proto=either6
else
_proto=dhcp
fi
_ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
_ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}"
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same.
# so we have to avoid adding duplicates
# We should also check /proc/cmdline for existing ip=xx arg.
# For example, iscsi boot will specify ip=xxx arg in cmdline.
if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\
! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
echo "$_ip_opts" >> $_ip_conf
fi
if kdump_is_bridge "$_netdev"; then
kdump_setup_bridge "$_netdev"
elif kdump_is_bond "$_netdev"; then
kdump_setup_bond "$_netdev"
elif kdump_is_team "$_netdev"; then
kdump_setup_team "$_netdev"
elif kdump_is_vlan "$_netdev"; then
kdump_setup_vlan "$_netdev"
else
_ifname_opts=" ifname=$(kdump_setup_ifname $_netdev):$_netmac"
echo "$_ifname_opts" >> $_ip_conf
fi
kdump_setup_dns "$_netdev"
}
get_ip_route_field()
{
if `echo $1 | grep -q $2`; then
echo ${1##*$2} | cut -d ' ' -f1
fi
}
#Function:kdump_install_net
#$1: config values of net line in kdump.conf
#$2: srcaddr of network device
kdump_install_net() {
local _server _netdev _srcaddr _route _serv_tmp
local config_val="$1"
_server=$(get_remote_host $config_val)
if is_hostname $_server; then
_serv_tmp=`getent ahosts $_server | grep -v : | head -n 1`
if [ -z "$_serv_tmp" ]; then
_serv_tmp=`getent ahosts $_server | head -n 1`
fi
_server=`echo $_serv_tmp | cut -d' ' -f1`
fi
_route=`/sbin/ip -o route get to $_server 2>&1`
[ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1
#the field in the ip output changes if we go to another subnet
_srcaddr=$(get_ip_route_field "$_route" "src")
_netdev=$(get_ip_route_field "$_route" "dev")
kdump_setup_netdev "${_netdev}" "${_srcaddr}"
#save netdev used for kdump as cmdline
# Whoever calling kdump_install_net() is setting up the default gateway,
# ie. bootdev/kdumpnic. So don't override the setting if calling
# kdump_install_net() for another time. For example, after setting eth0 as
# the default gate way for network dump, eth1 in the fence kdump path will
# call kdump_install_net again and we don't want eth1 to be the default
# gateway.
if [ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ] &&
[ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]; then
echo "kdumpnic=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/60kdumpnic.conf
echo "bootdev=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/70bootdev.conf
fi
}
default_dump_target_install_conf()
{
local _target _fstype
local _mntpoint _save_path
is_user_configured_dump_target && return
_save_path=$(get_option_value "path")
[ -z "$_save_path" ] && _save_path=$DEFAULT_PATH
# strip the duplicated "/"
_save_path=$(echo $_save_path | tr -s /)
_mntpoint=$(get_mntpoint_from_path $_save_path)
_target=$(get_target_from_path $_save_path)
if is_atomic && is_bind_mount $_mntpoint; then
_save_path=${_save_path##"$_mntpoint"}
# the real dump path in the 2nd kernel, if the mount point is bind mounted.
_save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path
_mntpoint=$(get_mntpoint_from_target $_target)
# the absolute path in the 1st kernel
_save_path=$_mntpoint/$_save_path
fi
_fstype=$(get_fs_type_from_target $_target)
if is_fs_type_nfs $_fstype; then
kdump_install_net "$_target"
_fstype="nfs"
else
_target=$(kdump_get_persistent_dev $_target)
fi
echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf
# strip the duplicated "/"
_save_path=$(echo $_save_path | tr -s /)
# don't touch the path under root mount
if [ "$_mntpoint" != "/" ]; then
_save_path=${_save_path##"$_mntpoint"}
fi
#erase the old path line, then insert the parsed path
sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf
echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf
}
adjust_bind_mount_path()
{
local _target=$1
local _save_path=$(get_option_value "path")
[ -z "$_save_path" ] && _save_path=$DEFAULT_PATH
# strip the duplicated "/"
_save_path=$(echo $_save_path | tr -s /)
local _absolute_save_path=$(get_mntpoint_from_target $_target)/$_save_path
_absolute_save_path=$(echo "$_absolute_save_path" | tr -s /)
local _mntpoint=$(get_mntpoint_from_path $_absolute_save_path)
if is_bind_mount $_mntpoint; then
_save_path=${_absolute_save_path##"$_mntpoint"}
# the real dump path in the 2nd kernel, if the mount point is bind mounted.
_save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path
#erase the old path line, then insert the parsed path
sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf
echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf
fi
}
#install kdump.conf and what user specifies in kdump.conf
kdump_install_conf() {
local _opt _val _pdev
sed -ne '/^#/!p' /etc/kdump.conf > ${initdir}/tmp/$$-kdump.conf
while read _opt _val;
do
# remove inline comments after the end of a directive.
_val=$(strip_comments $_val)
case "$_opt" in
raw)
_pdev=$(persistent_policy="by-id" kdump_get_persistent_dev $_val)
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
;;
ext[234]|xfs|btrfs|minix)
_pdev=$(kdump_get_persistent_dev $_val)
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
if is_atomic; then
adjust_bind_mount_path "$_val"
fi
;;
ssh|nfs)
kdump_install_net "$_val"
;;
dracut_args)
if [[ $(get_dracut_args_fstype "$_val") = nfs* ]] ; then
kdump_install_net "$(get_dracut_args_target "$_val")"
fi
;;
kdump_pre|kdump_post|extra_bins)
dracut_install $_val
;;
core_collector)
dracut_install "${_val%%[[:blank:]]*}"
;;
esac
done < /etc/kdump.conf
default_dump_target_install_conf
kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf"
inst "${initdir}/tmp/$$-kdump.conf" "/etc/kdump.conf"
rm -f ${initdir}/tmp/$$-kdump.conf
}
# Default sysctl parameters should suffice for kdump kernel.
# Remove custom configurations sysctl.conf & sysctl.d/*
remove_sysctl_conf() {
# As custom configurations like vm.min_free_kbytes can lead
# to OOM issues in kdump kernel, avoid them
rm -f "${initdir}/etc/sysctl.conf"
rm -rf "${initdir}/etc/sysctl.d"
rm -rf "${initdir}/run/sysctl.d"
rm -rf "${initdir}/usr/lib/sysctl.d"
}
kdump_iscsi_get_rec_val() {
local result
# The open-iscsi 742 release changed to using flat files in
# /var/lib/iscsi.
result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = ")
result=${result##* = }
echo $result
}
kdump_get_iscsi_initiator() {
local _initiator
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
[ -f "$initiator_conf" ] || return 1
while read _initiator; do
[ -z "${_initiator%%#*}" ] && continue # Skip comment lines
case $_initiator in
InitiatorName=*)
initiator=${_initiator#InitiatorName=}
echo "rd.iscsi.initiator=${initiator}"
return 0;;
*) ;;
esac
done < ${initiator_conf}
return 1
}
# Figure out iBFT session according to session type
is_ibft() {
[ "$(kdump_iscsi_get_rec_val $1 "node.discovery_type")" = fw ]
}
kdump_setup_iscsi_device() {
local path=$1
local tgt_name; local tgt_ipaddr;
local username; local password; local userpwd_str;
local username_in; local password_in; local userpwd_in_str;
local netdev
local srcaddr
local idev
local netroot_str ; local initiator_str;
local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf"
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
dinfo "Found iscsi component $1"
# Check once before getting explicit values, so we can bail out early,
# e.g. in case of pure-hardware(all-offload) iscsi.
if ! /sbin/iscsiadm -m session -r ${path} &>/dev/null ; then
return 1
fi
if is_ibft ${path}; then
return
fi
# Remove software iscsi cmdline generated by 95iscsi,
# and let kdump regenerate here.
rm -f ${initdir}/etc/cmdline.d/95iscsi.conf
tgt_name=$(kdump_iscsi_get_rec_val ${path} "node.name")
tgt_ipaddr=$(kdump_iscsi_get_rec_val ${path} "node.conn\[0\].address")
# get and set username and password details
username=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username")
[ "$username" == "<empty>" ] && username=""
password=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password")
[ "$password" == "<empty>" ] && password=""
username_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username_in")
[ -n "$username" ] && userpwd_str="$username:$password"
# get and set incoming username and password details
[ "$username_in" == "<empty>" ] && username_in=""
password_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password_in")
[ "$password_in" == "<empty>" ] && password_in=""
[ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in"
netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \
sed 's|.*dev \(.*\).*|\1|g')
srcaddr=$(echo $netdev | awk '{ print $3; exit }')
netdev=$(echo $netdev | awk '{ print $1; exit }')
kdump_setup_netdev $netdev $srcaddr
# prepare netroot= command line
# FIXME: Do we need to parse and set other parameters like protocol, port
# iscsi_iface_name, netdev_name, LUN etc.
if is_ipv6_address $tgt_ipaddr; then
tgt_ipaddr="[$tgt_ipaddr]"
fi
netroot_str="netroot=iscsi:${userpwd_str}${userpwd_in_str}@$tgt_ipaddr::::$tgt_name"
[[ -f $netroot_conf ]] || touch $netroot_conf
# If netroot target does not exist already, append.
if ! grep -q $netroot_str $netroot_conf; then
echo $netroot_str >> $netroot_conf
dinfo "Appended $netroot_str to $netroot_conf"
fi
# Setup initator
initiator_str=$(kdump_get_iscsi_initiator)
[ $? -ne "0" ] && derror "Failed to get initiator name" && return 1
# If initiator details do not exist already, append.
if ! grep -q "$initiator_str" $netroot_conf; then
echo "$initiator_str" >> $netroot_conf
dinfo "Appended "$initiator_str" to $netroot_conf"
fi
}
kdump_check_iscsi_targets () {
# If our prerequisites are not met, fail anyways.
type -P iscsistart >/dev/null || return 1
kdump_check_setup_iscsi() (
local _dev
_dev=$1
[[ -L /sys/dev/block/$_dev ]] || return
cd "$(readlink -f /sys/dev/block/$_dev)"
until [[ -d sys || -d iscsi_session ]]; do
cd ..
done
[[ -d iscsi_session ]] && kdump_setup_iscsi_device "$PWD"
)
[[ $hostonly ]] || [[ $mount_needs ]] && {
for_each_host_dev_and_slaves_all kdump_check_setup_iscsi
}
}
# retrieves fence_kdump nodes from Pacemaker cluster configuration
get_pcs_fence_kdump_nodes() {
local nodes
# get cluster nodes from cluster cib, get interface and ip address
nodelist=`pcs cluster cib | xmllint --xpath "/cib/status/node_state/@uname" -`
# nodelist is formed as 'uname="node1" uname="node2" ... uname="nodeX"'
# we need to convert each to node1, node2 ... nodeX in each iteration
for node in ${nodelist}; do
# convert $node from 'uname="nodeX"' to 'nodeX'
eval $node
nodename=$uname
# Skip its own node name
if [ "$nodename" = `hostname` -o "$nodename" = `hostname -s` ]; then
continue
fi
nodes="$nodes $nodename"
done
echo $nodes
}
# retrieves fence_kdump args from config file
get_pcs_fence_kdump_args() {
if [ -f $FENCE_KDUMP_CONFIG_FILE ]; then
. $FENCE_KDUMP_CONFIG_FILE
echo $FENCE_KDUMP_OPTS
fi
}
# setup fence_kdump in cluster
# setup proper network and install needed files
kdump_configure_fence_kdump () {
local kdump_cfg_file=$1
local nodes
local args
if is_generic_fence_kdump; then
nodes=$(get_option_value "fence_kdump_nodes")
elif is_pcs_fence_kdump; then
nodes=$(get_pcs_fence_kdump_nodes)
# set appropriate options in kdump.conf
echo "fence_kdump_nodes $nodes" >> ${kdump_cfg_file}
args=$(get_pcs_fence_kdump_args)
if [ -n "$args" ]; then
echo "fence_kdump_args $args" >> ${kdump_cfg_file}
fi
else
# fence_kdump not configured
return 1
fi
# setup network for each node
for node in ${nodes}; do
kdump_install_net $node
done
dracut_install /etc/hosts
dracut_install /etc/nsswitch.conf
dracut_install $FENCE_KDUMP_SEND
}
# Install a random seed used to feed /dev/urandom
# By the time kdump service starts, /dev/uramdom is already fed by systemd
kdump_install_random_seed() {
local poolsize=`cat /proc/sys/kernel/random/poolsize`
if [ ! -d ${initdir}/var/lib/ ]; then
mkdir -p ${initdir}/var/lib/
fi
dd if=/dev/urandom of=${initdir}/var/lib/random-seed \
bs=$poolsize count=1 2> /dev/null
}
install() {
kdump_install_conf
remove_sysctl_conf
if is_ssh_dump_target; then
kdump_install_random_seed
fi
dracut_install -o /etc/adjtime /etc/localtime
inst "$moddir/monitor_dd_progress" "/kdumpscripts/monitor_dd_progress"
chmod +x ${initdir}/kdumpscripts/monitor_dd_progress
inst "/bin/dd" "/bin/dd"
inst "/bin/tail" "/bin/tail"
inst "/bin/date" "/bin/date"
inst "/bin/sync" "/bin/sync"
inst "/bin/cut" "/bin/cut"
inst "/bin/head" "/bin/head"
inst "/sbin/makedumpfile" "/sbin/makedumpfile"
inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg"
inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh"
inst "$moddir/kdump.sh" "/usr/bin/kdump.sh"
inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service"
ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service"
inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh"
inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service"
# Replace existing emergency service and emergency target
cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service"
cp "$moddir/kdump-emergency.target" "$initdir/$systemdsystemunitdir/emergency.target"
# Also redirect dracut-emergency to kdump error handler
ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service"
# Check for all the devices and if any device is iscsi, bring up iscsi
# target. Ideally all this should be pushed into dracut iscsi module
# at some point of time.
kdump_check_iscsi_targets
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
# safely replace "reserved_memory=XXXX"(default value is 8192) with
# "reserved_memory=1024" to lower memory pressure under kdump. We do
# it unconditionally here, if "/etc/lvm/lvm.conf" doesn't exist, it
# actually does nothing.
sed -i -e \
's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1 1024/' \
${initdir}/etc/lvm/lvm.conf &>/dev/null
# Kdump turns out to require longer default systemd mount timeout
# than 1st kernel(90s by default), we use default 300s for kdump.
grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null
if [ $? -ne 0 ]; then
mkdir -p ${initdir}/etc/systemd/system.conf.d
echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf
echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf
fi
}

View File

@ -0,0 +1,28 @@
#!/bin/sh
SRC_FILE_MB=$1
while true
do
DD_PID=`pidof dd`
if [ -n "$DD_PID" ]; then
break
fi
done
while true
do
sleep 5
if [ ! -d /proc/$DD_PID ]; then
break
fi
kill -s USR1 $DD_PID
CURRENT_SIZE=`tail -n 1 /tmp/dd_progress_file | sed "s/[^0-9].*//g"`
[ -n "$CURRENT_SIZE" ] && {
CURRENT_MB=$(($CURRENT_SIZE / 1048576))
echo -e "Copied $CURRENT_MB MB / $SRC_FILE_MB MB\r"
}
done
rm -f /tmp/dd_progress_file

54
early-kdump-howto.txt Normal file
View File

@ -0,0 +1,54 @@
Early Kdump HOWTO
Introduction
Kdump service starts too late, so early crashes will have no chance to get
kdump kernel booting, this will cause crash information to be lost. It is
necessary to add a dracut module in order to load crash kernel and initramfs
as early as possible. You can provide "rd.earlykdump" in grub commandline
to enable, then the early kdump will load those files like the normal kdump,
which is disabled by default.
For the normal kdump service, it can check whether the early kdump has loaded
the crash kernel and initramfs. It has no conflict with the early kdump.
How to configure early kdump:
We assume if you're reading this document, you should already have kexec-tools
installed.
You can rebuild the initramfs with earlykdump support with below steps:
1. start kdump service to make sure kdump initramfs is created.
# systemctl start kdump
2. rebuild system initramfs with earlykdump support.
# dracut --add earlykdump
3. add rd.earlykdump in grub kernel command line.
Note: earlykdump initramfs size will be large because it includes vmlinuz and
kdump initramfs. And for step 2 if you are sure to overwrite system initramfs
you can backup the original initramfs and use "--force" option.
After making said changes, reboot your system to take effect. Of course, if you
want to disable early kdump, you can simply remove "rd.earlykdump" from kernel
boot parameters in grub, and reboot system like above.
Once the boot is completed, you can check the status of the early kdump support
on the command prompt:
# journalctl -x|grep early-kdump
Then, you will see some useful logs, for exapmle:
1. if early kdump is successful.
Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: early-kdump is enabled.
Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: kexec: loaded early-
kdump kernel
2. if early kdump is disabled.
Mar 09 10:02:47 localhost.localdomain dracut-cmdline[189]: early-kdump is disabled.
Limitation
At present, early kdump doesn't support fadump.

BIN
eppic_050615.tar.gz Normal file

Binary file not shown.

22
kdump-dep-generator.sh Normal file
View File

@ -0,0 +1,22 @@
#!/bin/sh
# More details about systemd generator:
# http://www.freedesktop.org/wiki/Software/systemd/Generators/
. /usr/lib/kdump/kdump-lib.sh
# If invokded with no arguments for testing purpose, output to /tmp to
# avoid overriding the existing.
dest_dir="/tmp"
if [ -n "$1" ]; then
dest_dir=$1
fi
systemd_dir=/usr/lib/systemd/system
kdump_wants=$dest_dir/kdump.service.wants
if is_ssh_dump_target; then
mkdir -p $kdump_wants
ln -sf $systemd_dir/network-online.target $kdump_wants/
fi

View File

@ -0,0 +1,35 @@
From 1ac3e4a570005707260ea3e74ac011bd926b168b Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Thu, 6 Sep 2018 13:56:18 +0800
Subject: [PATCH 51/55] kdump: fix an error that can not parse the e820
reserved region
When kexec-tools load the kernel and initramfs for kdump, kexec-tools will
read /proc/iomem and recreate the e820 ranges for kdump kernel. But it fails
to parse the e820 reserved region, because the memcmp() is case sensitive
when comparing the string. In fact, it may be "Reserved" or "reserved" in
the /proc/iomem, so we have to fix these cases.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Reviewed-by: Dave Young <dyoung@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/i386/crashdump-x86.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index 437e8a8..140f45b 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -289,6 +289,8 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
type = RANGE_PMEM;
} else if(memcmp(str,"reserved\n",9) == 0 ) {
type = RANGE_RESERVED;
+ } else if (memcmp(str, "Reserved\n", 9) == 0) {
+ type = RANGE_RESERVED;
} else if (memcmp(str, "GART\n", 5) == 0) {
gart_start = start;
gart_end = end;
--
1.8.3.1

View File

@ -0,0 +1,91 @@
Kdump-in-cluster-environment HOWTO
Introduction
Kdump is a kexec based crash dumping mechansim for Linux. This docuement
illustrate how to configure kdump in cluster environment to allow the kdump
crash recovery service complete without being preempted by traditional power
fencing methods.
Overview
Kexec/Kdump
Details about Kexec/Kdump are available in Kexec-Kdump-howto file and will not
be described here.
fence_kdump
fence_kdump is an I/O fencing agent to be used with the kdump crash recovery
service. When the fence_kdump agent is invoked, it will listen for a message
from the failed node that acknowledges that the failed node is executing the
kdump crash kernel. Note that fence_kdump is not a replacement for traditional
fencing methods. The fence_kdump agent can only detect that a node has entered
the kdump crash recovery service. This allows the kdump crash recovery service
complete without being preempted by traditional power fencing methods.
fence_kdump_send
fence_kdump_send is a utility used to send messages that acknowledge that the
node itself has entered the kdump crash recovery service. The fence_kdump_send
utility is typically run in the kdump kernel after a cluster node has
encountered a kernel panic. Once the cluster node has entered the kdump crash
recovery service, fence_kdump_send will periodically send messages to all
cluster nodes. When the fence_kdump agent receives a valid message from the
failed nodes, fencing is complete.
How to configure Pacemaker cluster environment:
If we want to use kdump in Pacemaker cluster environment, fence-agents-kdump
should be installed in every nodes in the cluster. You can achieve this via
the following command:
# yum install -y fence-agents-kdump
Next is to add kdump_fence to the cluster. Assuming that the cluster consists
of three nodes, they are node1, node2 and node3, and use Pacemaker to perform
resource management and pcs as cli configuration tool.
With pcs it is easy to add a stonith resource to the cluster. For example, add
a stonith resource named mykdumpfence with fence type of fence_kdump via the
following commands:
# pcs stonith create mykdumpfence fence_kdump \
pcmk_host_check=static-list pcmk_host_list="node1 node2 node3"
# pcs stonith update mykdumpfence pcmk_monitor_action=metadata --force
# pcs stonith update mykdumpfence pcmk_status_action=metadata --force
# pcs stonith update mykdumpfence pcmk_reboot_action=off --force
Then enable stonith
# pcs property set stonith-enabled=true
How to configure kdump:
Actually there are two ways how to configure fence_kdump support:
1) Pacemaker based clusters
If you have successfully configured fence_kdump in Pacemaker, there is
no need to add some special configuration in kdump. So please refer to
Kexec-Kdump-howto file for more information.
2) Generic clusters
For other types of clusters there are two configuration options in
kdump.conf which enables fence_kdump support:
fence_kdump_nodes <node(s)>
Contains list of cluster node(s) separated by space to send
fence_kdump notification to (this option is mandatory to enable
fence_kdump)
fence_kdump_args <arg(s)>
Command line arguments for fence_kdump_send (it can contain
all valid arguments except hosts to send notification to)
These options will most probably be configured by your cluster software,
so please refer to your cluster documentation how to enable fence_kdump
support.
Please be aware that these two ways cannot be combined and 2) has precedence
over 1). It means that if fence_kdump is configured using fence_kdump_nodes
and fence_kdump_args options in kdump.conf, Pacemaker configuration is not
used even if it exists.

165
kdump-lib-initramfs.sh Normal file
View File

@ -0,0 +1,165 @@
# These variables and functions are useful in 2nd kernel
. /lib/kdump-lib.sh
KDUMP_PATH="/var/crash"
CORE_COLLECTOR=""
DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -d 31"
DMESG_COLLECTOR="/sbin/vmcore-dmesg"
DEFAULT_ACTION="systemctl reboot -f"
DATEDIR=`date +%Y-%m-%d-%T`
HOST_IP='127.0.0.1'
DUMP_INSTRUCTION=""
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
KDUMP_SCRIPT_DIR="/kdumpscripts"
DD_BLKSIZE=512
FINAL_ACTION="systemctl reboot -f"
KDUMP_CONF="/etc/kdump.conf"
KDUMP_PRE=""
KDUMP_POST=""
NEWROOT="/sysroot"
get_kdump_confs()
{
local config_opt config_val
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
config_val=$(strip_comments $config_val)
case "$config_opt" in
path)
KDUMP_PATH="$config_val"
;;
core_collector)
[ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
;;
sshkey)
if [ -f "$config_val" ]; then
SSH_KEY_LOCATION=$config_val
fi
;;
kdump_pre)
KDUMP_PRE="$config_val"
;;
kdump_post)
KDUMP_POST="$config_val"
;;
fence_kdump_args)
FENCE_KDUMP_ARGS="$config_val"
;;
fence_kdump_nodes)
FENCE_KDUMP_NODES="$config_val"
;;
default)
case $config_val in
shell)
DEFAULT_ACTION="kdump_emergency_shell"
;;
reboot)
DEFAULT_ACTION="systemctl reboot -f"
;;
halt)
DEFAULT_ACTION="halt"
;;
poweroff)
DEFAULT_ACTION="poweroff"
;;
dump_to_rootfs)
DEFAULT_ACTION="dump_to_rootfs"
;;
esac
;;
esac
done < $KDUMP_CONF
if [ -z "$CORE_COLLECTOR" ]; then
CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
if is_ssh_dump_target || is_raw_dump_target; then
CORE_COLLECTOR="$CORE_COLLECTOR -F"
fi
fi
}
# dump_fs <mount point| device>
dump_fs()
{
local _dev=$(findmnt -k -f -n -r -o SOURCE $1)
local _mp=$(findmnt -k -f -n -r -o TARGET $1)
echo "kdump: dump target is $_dev"
if [ -z "$_mp" ]; then
echo "kdump: error: Dump target $_dev is not mounted."
return 1
fi
# Remove -F in makedumpfile case. We don't want a flat format dump here.
[[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"`
echo "kdump: saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
mount -o remount,rw $_mp || return 1
mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
echo "kdump: saving vmcore"
$CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1
mv $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore
sync
echo "kdump: saving vmcore complete"
# improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure
return 0
}
save_vmcore_dmesg_fs() {
local _dmesg_collector=$1
local _path=$2
echo "kdump: saving vmcore-dmesg.txt"
$_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt
_exitcode=$?
if [ $_exitcode -eq 0 ]; then
mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
# Make sure file is on disk. There have been instances where later
# saving vmcore failed and system rebooted without sync and there
# was no vmcore-dmesg.txt available.
sync
echo "kdump: saving vmcore-dmesg.txt complete"
else
echo "kdump: saving vmcore-dmesg.txt failed"
fi
}
dump_to_rootfs()
{
echo "Kdump: trying to bring up rootfs device"
systemctl start dracut-initqueue
echo "Kdump: waiting for rootfs mount, will timeout after 90 seconds"
systemctl start sysroot.mount
dump_fs $NEWROOT
}
kdump_emergency_shell()
{
echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile
/bin/dracut-emergency
rm -f /etc/profile
}
do_default_action()
{
echo "Kdump: Executing default action $DEFAULT_ACTION"
eval $DEFAULT_ACTION
}
do_final_action()
{
eval $FINAL_ACTION
}

709
kdump-lib.sh Normal file
View File

@ -0,0 +1,709 @@
#!/bin/sh
#
# Kdump common variables and functions
#
DEFAULT_PATH="/var/crash/"
FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump"
FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send"
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
is_fadump_capable()
{
# Check if firmware-assisted dump is enabled
# if no, fallback to kdump check
if [ -f $FADUMP_ENABLED_SYS_NODE ]; then
rc=`cat $FADUMP_ENABLED_SYS_NODE`
[ $rc -eq 1 ] && return 0
fi
return 1
}
perror_exit() {
echo $@ >&2
exit 1
}
perror() {
echo $@ >&2
}
is_ssh_dump_target()
{
grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf
}
is_nfs_dump_target()
{
grep -q "^nfs" /etc/kdump.conf || \
[[ $(get_dracut_args_fstype "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)") = nfs* ]]
}
is_raw_dump_target()
{
grep -q "^raw" /etc/kdump.conf
}
is_fs_type_nfs()
{
local _fstype=$1
[ $_fstype = "nfs" ] || [ $_fstype = "nfs4" ] && return 0
return 1
}
is_fs_dump_target()
{
egrep -q "^ext[234]|^xfs|^btrfs|^minix" /etc/kdump.conf
}
strip_comments()
{
echo $@ | sed -e 's/\(.*\)#.*/\1/'
}
# Check if fence kdump is configured in Pacemaker cluster
is_pcs_fence_kdump()
{
# no pcs or fence_kdump_send executables installed?
type -P pcs > /dev/null || return 1
[ -x $FENCE_KDUMP_SEND ] || return 1
# fence kdump not configured?
(pcs cluster cib | grep 'type="fence_kdump"') &> /dev/null || return 1
}
# Check if fence_kdump is configured using kdump options
is_generic_fence_kdump()
{
[ -x $FENCE_KDUMP_SEND ] || return 1
grep -q "^fence_kdump_nodes" /etc/kdump.conf
}
to_dev_name() {
local dev="${1//\"/}"
case "$dev" in
UUID=*)
dev=`blkid -U "${dev#UUID=}"`
;;
LABEL=*)
dev=`blkid -L "${dev#LABEL=}"`
;;
esac
echo $dev
}
is_user_configured_dump_target()
{
return $(is_mount_in_dracut_args || is_ssh_dump_target || is_nfs_dump_target || \
is_raw_dump_target || is_fs_dump_target)
}
get_user_configured_dump_disk()
{
local _target
_target=$(egrep "^ext[234]|^xfs|^btrfs|^minix|^raw" /etc/kdump.conf 2>/dev/null |awk '{print $2}')
[ -n "$_target" ] && echo $_target && return
_target=$(get_dracut_args_target "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)")
[ -b "$_target" ] && echo $_target
}
get_root_fs_device()
{
local _target
_target=$(findmnt -k -f -n -o SOURCE /)
[ -n "$_target" ] && echo $_target
return
}
get_save_path()
{
local _save_path=$(grep "^path" /etc/kdump.conf|awk '{print $2}')
if [ -z "$_save_path" ]; then
_save_path=$DEFAULT_PATH
fi
echo $_save_path
}
get_block_dump_target()
{
local _target _path
if is_ssh_dump_target || is_nfs_dump_target; then
return
fi
_target=$(get_user_configured_dump_disk)
[ -n "$_target" ] && echo $(to_dev_name $_target) && return
# Get block device name from local save path
_path=$(get_save_path)
_target=$(get_target_from_path $_path)
[ -b "$_target" ] && echo $(to_dev_name $_target)
}
is_dump_to_rootfs()
{
grep "^default[[:space:]]dump_to_rootfs" /etc/kdump.conf >/dev/null
}
get_default_action_target()
{
local _target
if is_dump_to_rootfs; then
# Get rootfs device name
_target=$(get_root_fs_device)
[ -b "$_target" ] && echo $(to_dev_name $_target) && return
# Then, must be nfs root
echo "nfs"
fi
}
# Get kdump targets(including root in case of dump_to_rootfs).
get_kdump_targets()
{
local _target _root
local kdump_targets
_target=$(get_block_dump_target)
if [ -n "$_target" ]; then
kdump_targets=$_target
elif is_ssh_dump_target; then
kdump_targets="ssh"
else
kdump_targets="nfs"
fi
# Add the root device if dump_to_rootfs is specified.
_root=$(get_default_action_target)
if [ -n "$_root" -a "$kdump_targets" != "$_root" ]; then
kdump_targets="$kdump_targets $_root"
fi
echo "$kdump_targets"
}
# findmnt uses the option "-v, --nofsroot" to exclusive the [/dir]
# in the SOURCE column for bind-mounts, then if $_mntpoint equals to
# $_mntpoint_nofsroot, the mountpoint is not bind mounted directory.
is_bind_mount()
{
local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}')
local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}')
if [[ $_mntpoint = $_mntpoint_nofsroot ]]; then
return 1
else
return 0
fi
}
# Below is just an example for mount info
# /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the
# directory is bind mounted. The former part represents the device path, rest
# part is the bind mounted directory which quotes by bracket "[]".
get_bind_mount_directory()
{
local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}')
local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}')
_mntpoint=${_mntpoint#*$_mntpoint_nofsroot}
_mntpoint=${_mntpoint#[}
_mntpoint=${_mntpoint%]}
echo $_mntpoint
}
get_mntpoint_from_path()
{
echo $(df $1 | tail -1 | awk '{print $NF}')
}
get_target_from_path()
{
local _target
_target=$(df $1 2>/dev/null | tail -1 | awk '{print $1}')
[[ "$_target" == "/dev/root" ]] && [[ ! -e /dev/root ]] && _target=$(get_root_fs_device)
echo $_target
}
get_fs_type_from_target()
{
echo $(findmnt -k -f -n -r -o FSTYPE $1)
}
# input: device path
# output: the general mount point
# find the general mount point, not the bind mounted point in atomic
# As general system, Use the previous code
#
# ERROR and EXIT:
# the device can be umounted the general mount point, if one of the mount point is bind mounted
# For example:
# mount /dev/sda /mnt/
# mount -o bind /mnt/var /var
# umount /mnt
get_mntpoint_from_target()
{
if is_atomic; then
for _mnt in $(findmnt -k -n -r -o TARGET $1)
do
if ! is_bind_mount $_mnt; then
echo $_mnt
return
fi
done
echo "Mount $1 firstly, without the bind mode" >&2
exit 1
else
echo $(findmnt -k -f -n -r -o TARGET $1)
fi
}
# get_option_value <option_name>
# retrieves value of option defined in kdump.conf
get_option_value() {
echo $(strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-`)
}
#This function compose a absolute path with the mount
#point and the relative $SAVE_PATH.
#target is passed in as argument, could be UUID, LABEL,
#block device or even nfs server export of the form of
#"my.server.com:/tmp/export"?
#And possibly this could be used for both default case
#as well as when dump taret is specified. When dump
#target is not specified, then $target would be null.
make_absolute_save_path()
{
local _target=$1
local _mnt
[ -n $_target ] && _mnt=$(get_mntpoint_from_target $1)
_mnt="${_mnt}/$SAVE_PATH"
# strip the duplicated "/"
echo "$_mnt" | tr -s /
}
check_save_path_fs()
{
local _path=$1
if [ ! -d $_path ]; then
perror_exit "Dump path $_path does not exist."
fi
}
is_atomic()
{
grep -q "ostree" /proc/cmdline
}
is_ipv6_address()
{
echo $1 | grep -q ":"
}
# get ip address or hostname from nfs/ssh config value
get_remote_host()
{
local _config_val=$1
# ipv6 address in kdump.conf is around with "[]",
# factor out the ipv6 address
_config_val=${_config_val#*@}
_config_val=${_config_val%:/*}
_config_val=${_config_val#[}
_config_val=${_config_val%]}
echo $_config_val
}
is_hostname()
{
local _hostname=`echo $1 | grep ":"`
if [ -n "$_hostname" ]; then
return 1
fi
echo $1 | grep -q "[a-zA-Z]"
}
# Copied from "/etc/sysconfig/network-scripts/network-functions"
get_hwaddr()
{
if [ -f "/sys/class/net/${1}/address" ]; then
awk '{ print toupper($0) }' < /sys/class/net/${1}/address
elif [ -d "/sys/class/net/${1}" ]; then
LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
"\\1", 1)); }'
fi
}
get_ifcfg_by_device()
{
grep -E -i -l "^[[:space:]]*DEVICE=\"*${1}\"*[[:space:]]*$" \
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
}
get_ifcfg_by_hwaddr()
{
grep -E -i -l "^[[:space:]]*HWADDR=\"*${1}\"*[[:space:]]*$" \
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
}
get_ifcfg_by_uuid()
{
grep -E -i -l "^[[:space:]]*UUID=\"*${1}\"*[[:space:]]*$" \
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
}
get_ifcfg_by_name()
{
grep -E -i -l "^[[:space:]]*NAME=\"*${1}\"*[[:space:]]*$" \
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
}
is_nm_running()
{
[ "$(LANG=C nmcli -t --fields running general status 2>/dev/null)" = "running" ]
}
is_nm_handling()
{
LANG=C nmcli -t --fields device,state dev status 2>/dev/null \
| grep -q "^\(${1}:connected\)\|\(${1}:connecting.*\)$"
}
# $1: netdev name
get_ifcfg_nmcli()
{
local nm_uuid nm_name
local ifcfg_file
# Get the active nmcli config name of $1
if is_nm_running && is_nm_handling "${1}" ; then
# The configuration "uuid" and "name" generated by nm is wrote to
# the ifcfg file as "UUID=<nm_uuid>" and "NAME=<nm_name>".
nm_uuid=$(LANG=C nmcli -t --fields uuid,device c show --active 2>/dev/null \
| grep "${1}" | head -1 | cut -d':' -f1)
nm_name=$(LANG=C nmcli -t --fields name,device c show --active 2>/dev/null \
| grep "${1}" | head -1 | cut -d':' -f1)
ifcfg_file=$(get_ifcfg_by_uuid "${nm_uuid}")
[ -z "${ifcfg_file}" ] && ifcfg_file=$(get_ifcfg_by_name "${nm_name}")
fi
echo -n "${ifcfg_file}"
}
# $1: netdev name
get_ifcfg_legacy()
{
local ifcfg_file
ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-${1}"
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
ifcfg_file=$(get_ifcfg_by_name "${1}")
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
local hwaddr=$(get_hwaddr "${1}")
if [ -n "$hwaddr" ]; then
ifcfg_file=$(get_ifcfg_by_hwaddr "${hwaddr}")
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
fi
ifcfg_file=$(get_ifcfg_by_device "${1}")
echo -n "${ifcfg_file}"
}
# $1: netdev name
# Return the ifcfg file whole name(including the path) of $1 if any.
get_ifcfg_filename() {
local ifcfg_file
ifcfg_file=$(get_ifcfg_nmcli "${1}")
if [ -z "${ifcfg_file}" ]; then
ifcfg_file=$(get_ifcfg_legacy "${1}")
fi
echo -n "${ifcfg_file}"
}
# returns 0 when omission of watchdog module is desired in dracut_args
# returns 1 otherwise
is_wdt_mod_omitted() {
local dracut_args
local ret=1
dracut_args=$(grep "^dracut_args" /etc/kdump.conf)
[[ -z $dracut_args ]] && return $ret
eval set -- $dracut_args
while :; do
[[ -z $1 ]] && break
case $1 in
-o|--omit)
echo $2 | grep -qw "watchdog"
[[ $? == 0 ]] && ret=0
break
esac
shift
done
return $ret
}
# If "dracut_args" contains "--mount" information, use it
# directly without any check(users are expected to ensure
# its correctness).
is_mount_in_dracut_args()
{
grep -q "^dracut_args .*\-\-mount" /etc/kdump.conf
}
# If $1 contains dracut_args "--mount", return <filesystem type>
get_dracut_args_fstype()
{
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3
}
# If $1 contains dracut_args "--mount", return <device>
get_dracut_args_target()
{
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1
}
check_crash_mem_reserved()
{
local mem_reserved
mem_reserved=$(cat /sys/kernel/kexec_crash_size)
if [ $mem_reserved -eq 0 ]; then
echo "No memory reserved for crash kernel"
return 1
fi
return 0
}
check_kdump_feasibility()
{
if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
echo "Kdump is not supported on this kernel"
return 1
fi
check_crash_mem_reserved
return $?
}
check_current_kdump_status()
{
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
}
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]
# Remove a list of kernel parameters from a given kernel cmdline and print the result.
# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.
remove_cmdline_param()
{
local cmdline=$1
shift
for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
done
echo $cmdline
}
#
# This function returns the "apicid" of the boot
# cpu (cpu 0) if present.
#
get_bootcpu_apicid()
{
awk ' \
BEGIN { CPU = "-1"; } \
$1=="processor" && $2==":" { CPU = $NF; } \
CPU=="0" && /^apicid/ { print $NF; } \
' \
/proc/cpuinfo
}
#
# append_cmdline <kernel cmdline> <parameter name> <parameter value>
# This function appends argument "$2=$3" to string ($1) if not already present.
#
append_cmdline()
{
local cmdline=$1
local newstr=${cmdline/$2/""}
# unchanged str implies argument wasn't there
if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
fi
echo $cmdline
}
# This function check iomem and determines if we have more than
# 4GB of ram available. Returns 1 if we do, 0 if we dont
need_64bit_headers()
{
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
}
# Check if secure boot is being enforced.
#
# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and
# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four
# bytes are the attributes associated with the variable and can safely be
# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot
# is 1 and SetupMode is 0, then secure boot is being enforced.
#
# Assume efivars is mounted at /sys/firmware/efi/efivars.
is_secure_boot_enforced()
{
local secure_boot_file setup_mode_file
local secure_boot_byte setup_mode_byte
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
fi
return 1
}
#
# prepare_kexec_args <kexec args>
# This function prepares kexec argument.
#
prepare_kexec_args()
{
local kexec_args=$1
local found_elf_args
ARCH=`uname -m`
if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
then
need_64bit_headers
if [ $? == 1 ]
then
found_elf_args=`echo $kexec_args | grep elf32-core-headers`
if [ -n "$found_elf_args" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
echo
else
kexec_args="$kexec_args --elf64-core-headers"
fi
else
found_elf_args=`echo $kexec_args | grep elf64-core-headers`
if [ -z "$found_elf_args" ]
then
kexec_args="$kexec_args --elf32-core-headers"
fi
fi
fi
echo $kexec_args
}
check_boot_dir()
{
local kdump_bootdir=$1
#If user specify a boot dir for kdump kernel, let's use it. Otherwise
#check whether it's a atomic host. If yes parse the subdirectory under
#/boot; If not just find it under /boot.
if [ -n "$kdump_bootdir" ]; then
echo "$kdump_bootdir"
return
fi
if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then
kdump_bootdir="/boot"
else
eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1)
kdump_bootdir="/boot"$(dirname $BOOT_IMAGE)
fi
echo $kdump_bootdir
}
#
# prepare_cmdline <commandline> <commandline remove> <commandline append>
# This function performs a series of edits on the command line.
# Store the final result in global $KDUMP_COMMANDLINE.
prepare_cmdline()
{
local cmdline id
if [ -z "$1" ]; then
cmdline=$(cat /proc/cmdline)
else
cmdline="$1"
fi
# These params should always be removed
cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
# These params can be removed configurably
cmdline=$(remove_cmdline_param "$cmdline" "$2")
# Always remove "root=X", as we now explicitly generate all kinds
# of dump target mount information including root fs.
#
# We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
# about it(e.g. for debug purpose), then can pass "root=X" using
# KDUMP_COMMANDLINE_APPEND.
cmdline=$(remove_cmdline_param "$cmdline" root)
# With the help of "--hostonly-cmdline", we can avoid some interitage.
cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
# Remove netroot, rd.iscsi.initiator and iscsi_initiator since
# we get duplicate entries for the same in case iscsi code adds
# it as well.
cmdline=$(remove_cmdline_param "$cmdline" netroot rd.iscsi.initiator iscsi_initiator)
cmdline="${cmdline} $3"
id=$(get_bootcpu_apicid)
if [ ! -z ${id} ] ; then
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
fi
echo ${cmdline}
}

163
kdump.conf Normal file
View File

@ -0,0 +1,163 @@
# This file contains a series of commands to perform (in order) in the kdump
# kernel after a kernel crash in the crash kernel(1st kernel) has happened.
#
# Directives in this file are only applicable to the kdump initramfs, and have
# no effect once the root filesystem is mounted and the normal init scripts are
# processed.
#
# Currently, only one dump target and path can be specified. If the dumping to
# the configured target fails, the default action which can be configured via
# the "default" directive will be performed.
#
# Supported options:
#
# raw <partition>
# - Will dd /proc/vmcore into <partition>.
# Use persistent device names for partition devices,
# such as /dev/vg/<devname>.
#
# nfs <nfs mount>
# - Will mount nfs to <mnt>, and copy /proc/vmcore to
# <mnt>/<path>/%HOST-%DATE/, supports DNS.
#
# ssh <user@server>
# - Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
# supports DNS.
# NOTE: make sure the user has write permissions on the server.
#
# sshkey <path>
# - Will use the sshkey to do ssh dump.
# Specify the path of the ssh key to use when dumping
# via ssh. The default value is /root/.ssh/kdump_id_rsa.
#
# <fs type> <partition>
# - Will mount -t <fs type> <partition> <mnt>, and copy
# /proc/vmcore to <mnt>/<path>/%DATE/.
# NOTE: <partition> can be a device node, label or uuid.
# It's recommended to use persistent device names
# such as /dev/vg/<devname>.
# Otherwise it's suggested to use label or uuid.
#
# path <path>
# - "path" represents the file system path in which vmcore
# will be saved. If a dump target is specified in
# kdump.conf, then "path" is relative to the specified
# dump target.
#
# Interpretation of "path" changes a bit if the user didn't
# specify any dump target explicitly in kdump.conf. In this
# case, "path" represents the absolute path from root. The
# dump target and adjusted path are arrived at automatically
# depending on what's mounted in the current system.
#
# Ignored for raw device dumps. If unset, will use the default
# "/var/crash".
#
# core_collector <command> <options>
# - This allows you to specify the command to copy
# the vmcore. The default is makedumpfile, which on
# some architectures can drastically reduce vmcore size.
# See /sbin/makedumpfile --help for a list of options.
# Note that the -i and -g options are not needed here,
# as the initrd will automatically be populated with a
# config file appropriate for the running kernel.
# The default core_collector for raw/ssh dump is:
# "makedumpfile -F -l --message-level 1 -d 31".
# The default core_collector for other targets is:
# "makedumpfile -l --message-level 1 -d 31".
#
# "makedumpfile -F" will create a flattened vmcore.
# You need to use "makedumpfile -R" to rearrange the dump data to
# a normal dumpfile readable with analysis tools. For example:
# "makedumpfile -R vmcore < vmcore.flat".
#
# For core_collector format details, you can refer to
# kexec-kdump-howto.txt or kdump.conf manpage.
#
# kdump_post <binary | script>
# - This directive allows you to run a executable binary
# or script after the vmcore dump process terminates.
# The exit status of the current dump process is fed to
# the executable binary or script as its first argument.
#
# kdump_pre <binary | script>
# - Works like the "kdump_post" directive, but instead of running
# after the dump process, runs immediately before it.
# Exit status of this binary is interpreted as follows:
# 0 - continue with dump process as usual
# non 0 - reboot the system
#
# extra_bins <binaries | shell scripts>
# - This directive allows you to specify additional binaries or
# shell scripts to be included in the kdump initrd.
# Generally they are useful in conjunction with a kdump_post
# or kdump_pre binary or script which depends on these extra_bins.
#
# extra_modules <module(s)>
# - This directive allows you to specify extra kernel modules
# that you want to be loaded in the kdump initrd.
# Multiple modules can be listed, separated by spaces, and any
# dependent modules will automatically be included.
#
# default <reboot | halt | poweroff | shell | dump_to_rootfs>
# - Action to perform in case dumping fails.
# reboot: Reboot the system.
# halt: Halt the system.
# poweroff: Power down the system.
# shell: Drop to a bash shell.
# Exiting the shell reboots the system.
# dump_to_rootfs: Dump vmcore to rootfs from initramfs context and
# reboot. Useful when non-root dump target is specified.
# The default option is "reboot".
#
# force_rebuild <0 | 1>
# - By default, kdump initrd will only be rebuilt when necessary.
# Specify 1 to force rebuilding kdump initrd every time when kdump
# service starts.
#
# force_no_rebuild <0 | 1>
# - By default, kdump initrd will be rebuilt when necessary.
# Specify 1 to bypass rebuilding of kdump initrd.
#
# force_no_rebuild and force_rebuild options are mutually
# exclusive and they should not be set to 1 simultaneously.
#
# override_resettable <0 | 1>
# - Usually an unresettable block device can't be a dump target.
# Specifying 1 when you want to dump even though the block
# target is unresettable
# By default, it is 0, which will not try dumping destined to fail.
#
# dracut_args <arg(s)>
# - Pass extra dracut options when rebuilding kdump initrd.
#
# fence_kdump_args <arg(s)>
# - Command line arguments for fence_kdump_send (it can contain
# all valid arguments except hosts to send notification to).
#
# fence_kdump_nodes <node(s)>
# - List of cluster node(s) except localhost, separated by spaces,
# to send fence_kdump notifications to.
# (this option is mandatory to enable fence_kdump).
#
#raw /dev/vg/lv_kdump
#ext4 /dev/vg/lv_kdump
#ext4 LABEL=/boot
#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
#nfs my.server.com:/export/tmp
#ssh user@my.server.com
#sshkey /root/.ssh/kdump_id_rsa
path /var/crash
core_collector makedumpfile -l --message-level 1 -d 31
#core_collector scp
#kdump_post /var/crash/scripts/kdump-post.sh
#kdump_pre /var/crash/scripts/kdump-pre.sh
#extra_bins /usr/bin/lftp
#extra_modules gfs2
#default shell
#force_rebuild 1
#force_no_rebuild 1
#dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3"
#fence_kdump_args -p 7410 -f auto -c 0 -i 10
#fence_kdump_nodes node1 node2

344
kdump.conf.5 Normal file
View File

@ -0,0 +1,344 @@
.TH KDUMP.CONF 5 "07/23/2008" "kexec-tools"
.SH NAME
kdump.conf \- configuration file for kdump kernel.
.SH DESCRIPTION
kdump.conf is a configuration file for the kdump kernel crash
collection service.
kdump.conf provides post-kexec instructions to the kdump kernel. It is
stored in the initrd file managed by the kdump service. If you change
this file and do not want to reboot in order for the changes to take
effect, restart the kdump service to rebuild the initrd.
For most configurations, you can simply review the examples provided
in the stock /etc/kdump.conf.
.B NOTE:
For filesystem dumps the dump target must be mounted before building
kdump initramfs.
kdump.conf only affects the behavior of the initramfs. Please read the
kdump operational flow section of kexec-kdump-howto.txt in the docs to better
understand how this configuration file affects the behavior of kdump.
.SH OPTIONS
.B raw <partition>
.RS
Will dd /proc/vmcore into <partition>. Use persistent device names for
partition devices, such as /dev/vg/<devname>.
.RE
.B nfs <nfs mount>
.RS
Will mount nfs to <mnt>, and copy /proc/vmcore to <mnt>/<path>/%HOST-%DATE/,
supports DNS. Note that a fqdn should be used as the server name in the
mount point.
.RE
.B ssh <user@server>
.RS
Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
supports DNS. NOTE: make sure user has necessary write permissions on
server and that a fqdn is used as the server name.
.RE
.B sshkey <path>
.RS
Specify the path of the ssh key to use when dumping via ssh.
The default value is /root/.ssh/kdump_id_rsa.
.RE
.B <fs type> <partition>
.RS
Will mount -t <fs type> <partition> <mnt>, and copy /proc/vmcore to
<mnt>/<path>/%DATE/. NOTE: <partition> can be a device node, label
or uuid. It's recommended to use persistent device names such as
/dev/vg/<devname>. Otherwise it's suggested to use label or uuid.
.RE
.B path <path>
.RS
"path" represents the file system path in which vmcore will be saved.
If a dump target is specified in kdump.conf, then "path" is relative to the
specified dump target.
.PP
Interpretation of "path" changes a bit if the user didn't specify any dump
target explicitly in kdump.conf. In this case, "path" represents the
absolute path from root. The dump target and adjusted path are arrived
at automatically depending on what's mounted in the current system.
.PP
Ignored for raw device dumps. If unset, will use the default "/var/crash".
.RE
.B core_collector <command> <options>
.RS
This allows you to specify the command to copy the vmcore.
The default is makedumpfile, which on some architectures can drastically reduce
core file size. See /sbin/makedumpfile --help for a list of options.
Note that the -i and -g options are not needed here, as the initrd
will automatically be populated with a config file appropriate
for the running kernel.
.PP
Note 1: About default core collector:
The default core_collector for raw/ssh dump is:
"makedumpfile -F -l --message-level 1 -d 31".
The default core_collector for other targets is:
"makedumpfile -l --message-level 1 -d 31".
Even if core_collector option is commented out in kdump.conf, makedumpfile
is the default core collector and kdump uses it internally.
If one does not want makedumpfile as default core_collector, then they
need to specify one using core_collector option to change the behavior.
.PP
Note 2: If "makedumpfile -F" is used then you will get a flattened format
vmcore.flat, you will need to use "makedumpfile -R" to rearrange the
dump data from standard input to a normal dumpfile (readable with analysis
tools).
ie. "makedumpfile -R vmcore < vmcore.flat"
.RE
.B kdump_post <binary | script>
.RS
This directive allows you to run a specified executable
just after the vmcore dump process terminates. The exit
status of the current dump process is fed to the kdump_post
executable as its first argument($1). Executable can modify
it to indicate the new exit status of succeeding dump process,
.PP
Note that scripts written for use with this directive must use
the /bin/bash interpreter.
.RE
.B kdump_pre <binary | script>
.RS
Works just like the "kdump_post" directive, but instead
of running after the dump process, runs immediately
before. Exit status of this binary is interpreted
as follows:
.PP
0 - continue with dump process as usual
.PP
non 0 - reboot the system
.PP
Note that scripts written for this directive must use
the /bin/bash interpreter.
.RE
.B extra_bins <binaries | shell scripts>
.RS
This directive allows you to specify additional
binaries or shell scripts you'd like to include in
your kdump initrd. Generally only useful in
conjunction with a kdump_post binary or script that
relies on other binaries or scripts.
.RE
.B extra_modules <module(s)>
.RS
This directive allows you to specify extra kernel
modules that you want to be loaded in the kdump
initrd, typically used to set up access to
non-boot-path dump targets that might otherwise
not be accessible in the kdump environment. Multiple
modules can be listed, separated by spaces, and any
dependent modules will automatically be included.
.RE
.B default <reboot | halt | poweroff | shell | dump_to_rootfs>
.RS
Action to perform in case dumping to the intended target fails. The default is "reboot".
reboot: Reboot the system (this is what most people will want, as it returns the system
to a normal state). halt: Halt the system and lose the vmcore. poweroff: The system
will be powered down. shell: Drop to a shell session inside the initramfs, from which
you can manually perform additional recovery actions. Exiting this shell reboots the
system. Note: kdump uses bash as the default shell. dump_to_rootfs: If non-root dump
target is specified, the default action can be set as dump_to_rootfs. That means when
dumping to target fails, dump vmcore to rootfs from initramfs context and reboot.
.RE
.B force_rebuild <0 | 1>
.RS
By default, kdump initrd will only be rebuilt when necessary.
Specify 1 to force rebuilding kdump initrd every time when kdump service starts.
.RE
.B force_no_rebuild <0 | 1>
.RS
By default, kdump initrd will be rebuilt when necessary.
Specify 1 to bypass rebuilding of kdump initrd.
.PP
force_no_rebuild and force_rebuild options are mutually exclusive and
they should not be set to 1 simultaneously.
.RE
.B override_resettable <0 | 1>
.RS
Usually an unresettable block device can't be a dump target. Specifying 1 means
that even though the block target is unresettable, the user wants to try dumping anyway.
By default, it's set to 0, which will not try something destined to fail.
.RE
.B dracut_args <arg(s)>
.RS
Kdump uses dracut to generate initramfs for second kernel. This option
allows a user to pass arguments to dracut directly.
.RE
.B fence_kdump_args <arg(s)>
.RS
Command line arguments for fence_kdump_send (it can contain all valid
arguments except hosts to send notification to).
.RE
.B fence_kdump_nodes <node(s)>
.RS
List of cluster node(s) except localhost, separated by spaces, to send fence_kdump notification
to (this option is mandatory to enable fence_kdump).
.RE
.SH DEPRECATED OPTIONS
.B net <nfs mount>|<user@server>
.RS
net option is replaced by nfs and ssh options. Use nfs or ssh options
directly.
.RE
.B options <module> <option list>
.RS
Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump to add module options as
kernel command line parameters. For example, specify 'loop.max_loop=1' to limit
maximum loop devices to 1.
.RE
.B link_delay <seconds>
.RS
link_delay was used to wait for a network device to initialize before using it.
Now dracut network module takes care of this issue automatically.
.RE
.B disk_timeout <seconds>
.RS
Similar to link_delay, dracut ensures disks are ready before kdump uses them.
.RE
.B debug_mem_level <0-3>
.RS
Turn on verbose debug output of kdump scripts regarding free/used memory at
various points of execution. This feature has been
moved to dracut now.
Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump and
append dracut cmdline param rd.memdebug=[0-3] to enable the debug output.
Higher level means more debugging output.
.PP
0 - no output
.PP
1 - partial /proc/meminfo
.PP
2 - /proc/meminfo
.PP
3 - /proc/meminfo + /proc/slabinfo
.RE
.B blacklist <list of kernel modules>
.RS
blacklist option was recently being used to prevent loading modules in
initramfs. General terminology for blacklist has been that module is
present in initramfs but it is not actually loaded in kernel. Hence
retaining blacklist option creates more confusing behavior. It has been
deprecated.
.PP
Instead, use rd.driver.blacklist option on second kernel to blacklist
a certain module. One can edit /etc/sysconfig/kdump.conf and edit
KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer
to dracut.cmdline man page for more details on module blacklist option.
.RE
.RE
.SH EXAMPLES
Here are some examples for core_collector option:
.PP
Core collector command format depends on dump target type. Typically for
filesystem (local/remote), core_collector should accept two arguments.
First one is source file and second one is target file. For ex.
.TP
ex1.
core_collector "cp --sparse=always"
Above will effectively be translated to:
cp --sparse=always /proc/vmcore <dest-path>/vmcore
.TP
ex2.
core_collector "makedumpfile -l --message-level 1 -d 31"
Above will effectively be translated to:
makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dest-path>/vmcore
.PP
For dump targets like raw and ssh, in general, core collector should expect
one argument (source file) and should output the processed core on standard
output (There is one exception of "scp", discussed later). This standard
output will be saved to destination using appropriate commands.
raw dumps examples:
.TP
ex3.
core_collector "cat"
Above will effectively be translated to.
cat /proc/vmcore | dd of=<target-device>
.TP
ex4.
core_collector "makedumpfile -F -l --message-level 1 -d 31"
Above will effectively be translated to.
makedumpfile -F -l --message-level 1 -d 31 | dd of=<target-device>
.PP
ssh dumps examples
.TP
ex5.
core_collector "cat"
Above will effectively be translated to.
cat /proc/vmcore | ssh <options> <remote-location> "dd of=path/vmcore"
.TP
ex6.
core_collector "makedumpfile -F -l --message-level 1 -d 31"
Above will effectively be translated to.
makedumpfile -F -l --message-level 1 -d 31 | ssh <options> <remote-location> "dd of=path/vmcore"
There is one exception to standard output rule for ssh dumps. And that is
scp. As scp can handle ssh destinations for file transfers, one can
specify "scp" as core collector for ssh targets (no output on stdout).
.TP
ex7.
core_collector "scp"
Above will effectively be translated to.
scp /proc/vmcore <user@host>:path/vmcore
.PP
examples for other options please see
.I /etc/kdump.conf
.SH SEE ALSO
kexec(8) mkdumprd(8) dracut.cmdline(7)

14
kdump.service Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=Crash recovery kernel arming
After=network.target network-online.target remote-fs.target basic.target
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/usr/bin/kdumpctl start
ExecStop=/usr/bin/kdumpctl stop
RemainAfterExit=yes
StartLimitInterval=0
[Install]
WantedBy=multi-user.target

37
kdump.sysconfig Normal file
View File

@ -0,0 +1,37 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS=""
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"

40
kdump.sysconfig.i386 Normal file
View File

@ -0,0 +1,40 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS=""
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"
#What is the images extension. Relocatable kernels don't have one
KDUMP_IMG_EXT=""

42
kdump.sysconfig.ppc64 Normal file
View File

@ -0,0 +1,42 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS="--dt-no-old-root"
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"
#What is the images extension. Relocatable kernels don't have one
KDUMP_IMG_EXT=""
#Specify the action after failure

42
kdump.sysconfig.ppc64le Normal file
View File

@ -0,0 +1,42 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS="--dt-no-old-root"
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"
#What is the images extension. Relocatable kernels don't have one
KDUMP_IMG_EXT=""
#Specify the action after failure

43
kdump.sysconfig.s390x Normal file
View File

@ -0,0 +1,43 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never"
# Any additional /sbin/mkdumprd arguments required.
MKDUMPRD_ARGS=""
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS=""
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"
#What is the images extension. Relocatable kernels don't have one
KDUMP_IMG_EXT=""

40
kdump.sysconfig.x86_64 Normal file
View File

@ -0,0 +1,40 @@
# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
# If no version is specified, then the init script will try to find a
# kdump kernel with the same version number as the running kernel.
KDUMP_KERNELVER=""
# The kdump commandline is the command line that needs to be passed off to
# the kdump kernel. This will likely match the contents of the grub kernel
# line. For example:
# KDUMP_COMMANDLINE="ro root=LABEL=/"
# Dracut depends on proper root= options, so please make sure that appropriate
# root= options are copied from /proc/cmdline. In general it is best to append
# command line options using "KDUMP_COMMANDLINE_APPEND=".
# If a command line is not specified, the default will be taken from
# /proc/cmdline
KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE
KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 acpi_no_memhotplug transparent_hugepage=never nokaslr"
# Any additional kexec arguments required. In most situations, this should
# be left empty
#
# Example:
# KEXEC_ARGS="--elf32-core-headers"
KEXEC_ARGS=""
#Where to find the boot image
#KDUMP_BOOTDIR="/boot"
#What is the image type used for kdump
KDUMP_IMG="vmlinuz"
#What is the images extension. Relocatable kernels don't have one
KDUMP_IMG_EXT=""

1110
kdumpctl Normal file

File diff suppressed because it is too large Load Diff

44
kdumpctl.8 Normal file
View File

@ -0,0 +1,44 @@
.TH KDUMPCTL 8 2015-07-13 kexec-tools
.SH NAME
kdumpctl \- control interface for kdump
.SH SYNOPSIS
.B kdumpctl
.I COMMAND
.SH DESCRIPTION
.B kdumpctl
is used to check or control the kdump service.
In most cases, you should use
.B systemctl
to start / stop / enable kdump service instead. However,
.B kdumpctl
provides more details for debug and a helper to setup ssh key authentication.
.SH COMMANDS
.TP
.I start
Start the service.
.TP
.I stop
Stop the service.
.TP
.I status
Prints the current status of kdump service.
It returns non-zero value if kdump is not operational.
.TP
.I restart
Is equal to
.I start; stop
.TP
.I propagate
Helps to setup key authentication for ssh storage since it's
impossible to use password authentication during kdump.
.TP
.I showmem
Prints the size of reserved memory for crash kernel in megabytes.
.SH "SEE ALSO"
.BR kdump.conf (5),
.BR mkdumprd (8)

View File

@ -0,0 +1,387 @@
From f4c1caaa97a2e019ccc00ab63e390c60d1c9454c Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 15 Jul 2019 11:32:56 +0530
Subject: [PATCH 18/20] kexec/arm64: Add support for handling zlib compressed
(Image.gz) image
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=f4c1caaa97a2e019ccc00ab63e390c60d1c9454c
Currently the kexec_file_load() support for arm64 doesn't allow
handling zlib compressed (i.e. Image.gz) image.
Since most distributions use 'make zinstall' rule inside
'arch/arm64/boot/Makefile' to install the arm64
Image.gz compressed file inside the boot destination directory (for e.g.
/boot), currently we cannot use kexec_file_load() to load vmlinuz (or
Image.gz):
# file /boot/vmlinuz
/boot/vmlinuz: gzip compressed data, was "Image", <..snip..>, max
compression, from Unix, original size 21945120
Now, since via kexec_file_load() we pass the 'fd' of Image.gz
(compressed file) via the following command line ...
# kexec -s -l /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname
-r`.img --reuse-cmdline
... kernel returns -EINVAL error value, as it is not able to locate
the magic number =0x644d5241, which is expected in the 64-byte header
of the decompressed kernel image.
We can fix this in user-space kexec-tools, which handles an
'Image.gz' being passed via kexec_file_load(), using an approach
as follows:
a). Copy the contents of Image.gz to a temporary file.
b). Decompress (gunzip-decompress) the contents inside the
temporary file.
c). Pass the 'fd' of the temporary file to the kernel space. So
basically the kernel space still gets a decompressed kernel
image to load via kexec-tools
I tested this patch for the following three use-cases:
1. Uncompressed Image file:
#kexec -s -l Image --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline
2. Signed Image file:
#kexec -s -l Image.signed --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline
3. zlib compressed Image.gz file:
#kexec -s -l /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/Makefile | 3 +-
kexec/arch/arm64/kexec-arm64.c | 1 +
kexec/arch/arm64/kexec-arm64.h | 7 ++
kexec/arch/arm64/kexec-image-arm64.c | 4 +-
kexec/arch/arm64/kexec-zImage-arm64.c | 226 ++++++++++++++++++++++++++++++++++
kexec/kexec.c | 12 ++
6 files changed, 250 insertions(+), 3 deletions(-)
create mode 100644 kexec/arch/arm64/kexec-zImage-arm64.c
diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile
index 9d9111c..d27c8ee 100644
--- a/kexec/arch/arm64/Makefile
+++ b/kexec/arch/arm64/Makefile
@@ -15,7 +15,8 @@ arm64_KEXEC_SRCS += \
kexec/arch/arm64/kexec-arm64.c \
kexec/arch/arm64/kexec-elf-arm64.c \
kexec/arch/arm64/kexec-uImage-arm64.c \
- kexec/arch/arm64/kexec-image-arm64.c
+ kexec/arch/arm64/kexec-image-arm64.c \
+ kexec/arch/arm64/kexec-zImage-arm64.c
arm64_UIMAGE = kexec/kexec-uImage.c
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 2992bce..eb3a3a3 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -71,6 +71,7 @@ struct file_type file_type[] = {
{"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage},
{"Image", image_arm64_probe, image_arm64_load, image_arm64_usage},
{"uImage", uImage_arm64_probe, uImage_arm64_load, uImage_arm64_usage},
+ {"zImage", zImage_arm64_probe, zImage_arm64_load, zImage_arm64_usage},
};
int file_types = sizeof(file_type) / sizeof(file_type[0]);
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index cc3419f..628de79 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -38,11 +38,18 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size);
int image_arm64_load(int argc, char **argv, const char *kernel_buf,
off_t kernel_size, struct kexec_info *info);
void image_arm64_usage(void);
+
int uImage_arm64_probe(const char *buf, off_t len);
int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
struct kexec_info *info);
void uImage_arm64_usage(void);
+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size);
+int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
+ off_t kernel_size, struct kexec_info *info);
+void zImage_arm64_usage(void);
+
+
off_t initrd_base;
off_t initrd_size;
diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
index 685a993..aa8f2e2 100644
--- a/kexec/arch/arm64/kexec-image-arm64.c
+++ b/kexec/arch/arm64/kexec-image-arm64.c
@@ -114,6 +114,6 @@ exit:
void image_arm64_usage(void)
{
printf(
-" An ARM64 binary image, compressed or not, big or little endian.\n"
-" Typically an Image, Image.gz or Image.lzma file.\n\n");
+" An ARM64 binary image, uncompressed, big or little endian.\n"
+" Typically an Image file.\n\n");
}
diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c
new file mode 100644
index 0000000..6ee82ff
--- /dev/null
+++ b/kexec/arch/arm64/kexec-zImage-arm64.c
@@ -0,0 +1,226 @@
+/*
+ * ARM64 kexec zImage (Image.gz) support.
+ *
+ * Several distros use 'make zinstall' rule inside
+ * 'arch/arm64/boot/Makefile' to install the arm64
+ * Image.gz compressed file inside the boot destination
+ * directory (for e.g. /boot).
+ *
+ * Currently we cannot use kexec_file_load() to load vmlinuz
+ * (or Image.gz).
+ *
+ * To support Image.gz, we should:
+ * a). Copy the contents of Image.gz to a temporary file.
+ * b). Decompress (gunzip-decompress) the contents inside the
+ * temporary file.
+ * c). Pass the 'fd' of the temporary file to the kernel space.
+ *
+ * So basically the kernel space still gets a decompressed
+ * kernel image to load via kexec-tools.
+ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "crashdump-arm64.h"
+#include "image-header.h"
+#include "kexec.h"
+#include "kexec-arm64.h"
+#include "kexec-syscall.h"
+#include "kexec-zlib.h"
+#include "arch/options.h"
+
+#define FILENAME_IMAGE "/tmp/ImageXXXXXX"
+
+/* Returns:
+ * -1 : in case of error/invalid format (not a valid Image.gz format.
+ * fd : File descriptor of the temp file containing the decompressed
+ * Image.
+ */
+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size)
+{
+ int ret = -1;
+ int fd = 0;
+ int kernel_fd = 0;
+ char *fname = NULL;
+ char *kernel_uncompressed_buf = NULL;
+ const struct arm64_image_header *h;
+
+ if (!is_zlib_file(kernel_buf, &kernel_size)) {
+ dbgprintf("%s: Not an zImage file (Image.gz).\n", __func__);
+ return -1;
+ }
+
+ if (!(fname = strdup(FILENAME_IMAGE))) {
+ dbgprintf("%s: Can't duplicate strings %s\n", __func__,
+ fname);
+ return -1;
+ }
+
+ if ((fd = mkstemp(fname)) < 0) {
+ dbgprintf("%s: Can't open file %s\n", __func__,
+ fname);
+ ret = -1;
+ goto fail_mkstemp;
+ }
+
+ kernel_uncompressed_buf =
+ (char *) calloc(kernel_size, sizeof(off_t));
+ if (!kernel_uncompressed_buf) {
+ dbgprintf("%s: Can't calloc %ld bytes\n",
+ __func__, kernel_size);
+ ret= -ENOMEM;
+ goto fail_calloc;
+ }
+
+ /* slurp in the input kernel */
+ dbgprintf("%s: ", __func__);
+ kernel_uncompressed_buf = slurp_decompress_file(kernel_buf,
+ &kernel_size);
+
+ /* check for correct header magic */
+ if (kernel_size < sizeof(struct arm64_image_header)) {
+ dbgprintf("%s: No arm64 image header.\n", __func__);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ h = (const struct arm64_image_header *)(kernel_uncompressed_buf);
+
+ if (!arm64_header_check_magic(h)) {
+ dbgprintf("%s: Bad arm64 image header.\n", __func__);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ if (write(fd, kernel_uncompressed_buf,
+ kernel_size) != kernel_size) {
+ dbgprintf("%s: Can't write the uncompressed file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ close(fd);
+
+ /* Open the tmp file again, this time in O_RDONLY mode, as
+ * opening the file in O_RDWR and calling kexec_file_load()
+ * causes the kernel to return -ETXTBSY
+ */
+ kernel_fd = open(fname, O_RDONLY);
+ if (kernel_fd == -1) {
+ dbgprintf("%s: Failed to open file %s\n",
+ __func__, fname);
+ ret = -1;
+ goto fail_bad_header;
+ }
+
+ unlink(fname);
+
+ free(kernel_uncompressed_buf);
+ free(fname);
+
+ return kernel_fd;
+
+fail_bad_header:
+ free(kernel_uncompressed_buf);
+
+fail_calloc:
+ if (fd >= 0)
+ close(fd);
+
+ unlink(fname);
+
+fail_mkstemp:
+ free(fname);
+
+ return ret;
+}
+
+int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
+ off_t kernel_size, struct kexec_info *info)
+{
+ const struct arm64_image_header *header;
+ unsigned long kernel_segment;
+ int result;
+
+ if (info->file_mode) {
+ if (arm64_opts.initrd) {
+ info->initrd_fd = open(arm64_opts.initrd, O_RDONLY);
+ if (info->initrd_fd == -1) {
+ fprintf(stderr,
+ "Could not open initrd file %s:%s\n",
+ arm64_opts.initrd, strerror(errno));
+ result = EFAILED;
+ goto exit;
+ }
+ }
+
+ if (arm64_opts.command_line) {
+ info->command_line = (char *)arm64_opts.command_line;
+ info->command_line_len =
+ strlen(arm64_opts.command_line) + 1;
+ }
+
+ return 0;
+ }
+
+ header = (const struct arm64_image_header *)(kernel_buf);
+
+ if (arm64_process_image_header(header))
+ return EFAILED;
+
+ kernel_segment = arm64_locate_kernel_segment(info);
+
+ if (kernel_segment == ULONG_MAX) {
+ dbgprintf("%s: Kernel segment is not allocated\n", __func__);
+ result = EFAILED;
+ goto exit;
+ }
+
+ dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment);
+ dbgprintf("%s: text_offset: %016lx\n", __func__,
+ arm64_mem.text_offset);
+ dbgprintf("%s: image_size: %016lx\n", __func__,
+ arm64_mem.image_size);
+ dbgprintf("%s: phys_offset: %016lx\n", __func__,
+ arm64_mem.phys_offset);
+ dbgprintf("%s: vp_offset: %016lx\n", __func__,
+ arm64_mem.vp_offset);
+ dbgprintf("%s: PE format: %s\n", __func__,
+ (arm64_header_check_pe_sig(header) ? "yes" : "no"));
+
+ /* create and initialize elf core header segment */
+ if (info->kexec_flags & KEXEC_ON_CRASH) {
+ result = load_crashdump_segments(info);
+ if (result) {
+ dbgprintf("%s: Creating eflcorehdr failed.\n",
+ __func__);
+ goto exit;
+ }
+ }
+
+ /* load the kernel */
+ add_segment_phys_virt(info, kernel_buf, kernel_size,
+ kernel_segment + arm64_mem.text_offset,
+ arm64_mem.image_size, 0);
+
+ /* load additional data */
+ result = arm64_load_other_segments(info, kernel_segment
+ + arm64_mem.text_offset);
+
+exit:
+ if (result)
+ fprintf(stderr, "kexec: load failed.\n");
+ return result;
+}
+
+void zImage_arm64_usage(void)
+{
+ printf(
+" An ARM64 zImage, compressed, big or little endian.\n"
+" Typically an Image.gz or Image.lzma file.\n\n");
+}
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 8ca3b45..bc6ab3d 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1206,8 +1206,20 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
kernel_buf = slurp_decompress_file(kernel, &kernel_size);
for (i = 0; i < file_types; i++) {
+#ifdef __aarch64__
+ /* handle Image.gz like cases */
+ if (is_zlib_file(kernel, &kernel_size)) {
+ if ((ret = file_type[i].probe(kernel, kernel_size)) >= 0) {
+ kernel_fd = ret;
+ break;
+ }
+ } else
+ if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
+ break;
+#else
if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
break;
+#endif
}
if (i == file_types) {
--
1.8.3.1

View File

@ -0,0 +1,67 @@
From 5570b42444661e212015abaca35b4dc698b9bb97 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 17 Dec 2018 00:46:54 +0530
Subject: [PATCH 23/37] kexec/dt-ops.c: Fix adding '/chosen' node for cases
where it is not available in dtb passed via --dtb option
While calling 'kexec -l', in case we are passed a .dtb using --dtb
option which doesn't contain a '/chosen' node, we try to create the
'/chosen' node and add bootargs to this node.
Currently the 'dt-ops.c' code is buggy as it passes '-FDT_ERR_NOTFOUND'
to 'fdt_add_subnode()', which leads to the following error:
# kexec -d --load Image --append 'debug' --dtb rk3399-sapphire.dtb
<..snip..>
dtb_set_property: fdt_add_subnode failed: FDT_ERR_NOTFOUND
kexec: Set device tree bootargs failed.
get_cells_size: #address-cells:2 #size-cells:2
cells_size_fitted: 0-0
cells_size_fitted: 0-0
setup_2nd_dtb: no kaslr-seed found
This patch passes the correct nodeoffset value to 'fdt_add_subnode()',
which fixes this issue:
# kexec -d -l Image --append 'debug' --dtb rk3399-sapphire.dtb
<..snip..>
get_cells_size: #address-cells:2 #size-cells:2
cells_size_fitted: 0-0
cells_size_fitted: 0-0
setup_2nd_dtb: no kaslr-seed found
Reported-by: Vicente Bergas <vicencb@gmail.com>
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/dt-ops.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c
index f15174c..bdc16dc 100644
--- a/kexec/dt-ops.c
+++ b/kexec/dt-ops.c
@@ -80,15 +80,16 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
}
nodeoffset = fdt_path_offset(new_dtb, node);
-
+
if (nodeoffset == -FDT_ERR_NOTFOUND) {
- result = fdt_add_subnode(new_dtb, nodeoffset, node);
+ result = fdt_add_subnode(new_dtb, 0, node);
if (result < 0) {
dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__,
fdt_strerror(result));
goto on_error;
}
+ nodeoffset = result;
} else if (nodeoffset < 0) {
dbgprintf("%s: fdt_path_offset failed: %s\n", __func__,
fdt_strerror(nodeoffset));
--
2.6.4.windows.1

View File

@ -0,0 +1,72 @@
From 583dbd57f99747fa891ddd517930af9699c2e936 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 17 Dec 2018 00:46:52 +0530
Subject: [PATCH 21/37] kexec/dt-ops.c: Fix check against 'fdt_add_subnode'
return value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Vicenç reported (via [1]) that currently executing kexec with
'--dtb' option and passing a .dtb which doesn't have a '/chosen' node
leads to the following error:
# kexec -d --dtb dtb_without_chosen_node.dtb --append 'cmdline' --load Image
dtb_set_property: fdt_add_subnode failed: <valid offset/length>
kexec: Set device tree bootargs failed.
This happens because currently we check the return value of
'fdt_add_subnode()' function call in 'dt-ops.c' incorrectly:
result = fdt_add_subnode(new_dtb, nodeoffset, node);
if (result) {
dbgprintf("%s: fdt_add_subnode failed: %s\n", _func__,
fdt_strerror(result));
goto on_error;
}
As we can see in 'fdt_rw.c', a positive return value from
'fdt_add_subnode()' function doesn't indicate an error.
We can see that the Linux kernel (see 'drivers/firmware/efi/libstub/fdt.c'
for example) also checks the 'fdt_add_subnode()' function against negative
return values for errors. See an example below from 'update_fdt()' function in
'drivers/firmware/efi/libstub/fdt.c':
node = fdt_add_subnode(fdt, 0, "chosen");
if (node < 0) {
status = node;
<..snip..>
goto fdt_set_fail;
}
This patch fixes the same in 'kexec-tools'.
[1]. http://lists.infradead.org/pipermail/kexec/2018-October/021746.html
Cc: Simon Horman <horms@verge.net.au>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Reported-by: Vicente Bergas <vicencb@gmail.com>
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/dt-ops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c
index 915dbf5..f15174c 100644
--- a/kexec/dt-ops.c
+++ b/kexec/dt-ops.c
@@ -84,7 +84,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
if (nodeoffset == -FDT_ERR_NOTFOUND) {
result = fdt_add_subnode(new_dtb, nodeoffset, node);
- if (result) {
+ if (result < 0) {
dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__,
fdt_strerror(result));
goto on_error;
--
2.6.4.windows.1

View File

@ -0,0 +1,104 @@
From f56cbcf4c2766e5e7d18808b33f2b71519be5207 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 17 Dec 2018 00:46:55 +0530
Subject: [PATCH 24/37] kexec/dt-ops.c: Fix '/chosen' v/s 'chosen' node being
passed to fdt helper functions
This patch fixes the incorrect 'chosen' node name being passed to
various fdt helper functions inside 'kexec/dt-ops.c'
As we can see from the Linux kernel usage inside
'drivers/firmware/efi/libstub/fdt.c', we pass '/chosen' node names to
fdt helper function like 'fdt_path_offset()' whereas 'chosen' to the
rest of the fdt helper functions like 'fdt_subnode_offset()'.
We need to replicate the same in 'kexec-tools' to fix issues being
reported when we use --dtb option while invoking 'kexec'.
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/dt-ops.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c
index bdc16dc..5626c47 100644
--- a/kexec/dt-ops.c
+++ b/kexec/dt-ops.c
@@ -8,7 +8,7 @@
#include "kexec.h"
#include "dt-ops.h"
-static const char n_chosen[] = "/chosen";
+static const char n_chosen[] = "chosen";
static const char p_bootargs[] = "bootargs";
static const char p_initrd_start[] = "linux,initrd-start";
@@ -58,6 +58,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
int nodeoffset;
void *new_dtb;
int new_size;
+ char *new_node = NULL;
value_len = FDT_TAGALIGN(value_len);
@@ -79,7 +80,16 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
goto on_error;
}
- nodeoffset = fdt_path_offset(new_dtb, node);
+ new_node = malloc(strlen("/") + strlen(node) + 1);
+ if (!new_node) {
+ dbgprintf("%s: malloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ strcpy(new_node, "/");
+ strcat(new_node, node);
+
+ nodeoffset = fdt_path_offset(new_dtb, new_node);
if (nodeoffset == -FDT_ERR_NOTFOUND) {
result = fdt_add_subnode(new_dtb, 0, node);
@@ -122,17 +132,29 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
on_error:
free(new_dtb);
+ free(new_node);
return result;
}
int dtb_delete_property(char *dtb, const char *node, const char *prop)
{
- int result;
- int nodeoffset = fdt_path_offset(dtb, node);
+ int result, nodeoffset;
+ char *new_node = NULL;
+
+ new_node = malloc(strlen("/") + strlen(node) + 1);
+ if (!new_node) {
+ dbgprintf("%s: malloc failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ strcpy(new_node, "/");
+ strcat(new_node, node);
+ nodeoffset = fdt_path_offset(dtb, new_node);
if (nodeoffset < 0) {
dbgprintf("%s: fdt_path_offset failed: %s\n", __func__,
fdt_strerror(nodeoffset));
+ free(new_node);
return nodeoffset;
}
@@ -142,5 +164,6 @@ int dtb_delete_property(char *dtb, const char *node, const char *prop)
dbgprintf("%s: fdt_delprop failed: %s\n", __func__,
fdt_strerror(nodeoffset));
+ free(new_node);
return result;
}
--
2.6.4.windows.1

View File

@ -0,0 +1,33 @@
From 9dcf363f509a1fa12a4d0d790a309a77c50aacaa Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 17 Dec 2018 00:46:53 +0530
Subject: [PATCH 22/37] kexec/kexec-arm64.c: Add error handling check against
return value of 'set_bootargs()'
This patch adds missing error handling check against the return value of
'set_bootargs()' in 'kexec-arm64.c'
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 8200064..6551b0f 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -406,6 +406,11 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash)
}
result = set_bootargs(dtb, command_line);
+ if (result) {
+ fprintf(stderr, "kexec: cannot set bootargs.\n");
+ result = -EINVAL;
+ goto on_error;
+ }
if (on_crash) {
/* determine #address-cells and #size-cells */
--
2.6.4.windows.1

View File

@ -0,0 +1,92 @@
From 0e709571bfe7e3b8160044970e2084194f9a963b Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 15 Jul 2019 11:32:55 +0530
Subject: [PATCH 17/20] kexec/kexec-zlib.h: Add 'is_zlib_file()' helper
function
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=0e709571bfe7e3b8160044970e2084194f9a963b
This patch adds 'is_zlib_file()' helper function which can be
used to quickly determine with the passed kernel image is a zlib
compressed kernel image.
This is specifically useful for arm64 zImage (or Image.gz) support,
which is introduced by later patches in this patchset.
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/kexec-zlib.h | 1 +
kexec/zlib.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/kexec/kexec-zlib.h b/kexec/kexec-zlib.h
index 43c107b..16300f2 100644
--- a/kexec/kexec-zlib.h
+++ b/kexec/kexec-zlib.h
@@ -6,5 +6,6 @@
#include "config.h"
+int is_zlib_file(const char *filename, off_t *r_size);
char *zlib_decompress_file(const char *filename, off_t *r_size);
#endif /* __KEXEC_ZLIB_H */
diff --git a/kexec/zlib.c b/kexec/zlib.c
index 95b6080..9bc340d 100644
--- a/kexec/zlib.c
+++ b/kexec/zlib.c
@@ -23,6 +23,38 @@ static void _gzerror(gzFile fp, int *errnum, const char **errmsg)
}
}
+int is_zlib_file(const char *filename, off_t *r_size)
+{
+ gzFile fp;
+ int errnum;
+ int is_zlib_file = 0; /* default: It's not in gzip format */
+ const char *msg;
+ ssize_t result;
+
+ if (!filename)
+ goto out;
+
+ fp = gzopen(filename, "rb");
+ if (fp == 0) {
+ _gzerror(fp, &errnum, &msg);
+ dbgprintf("Cannot open `%s': %s\n", filename, msg);
+ goto out;
+ }
+
+ if (!gzdirect(fp))
+ /* It's in gzip format */
+ is_zlib_file = 1;
+
+ result = gzclose(fp);
+ if (result != Z_OK) {
+ _gzerror(fp, &errnum, &msg);
+ dbgprintf(" Close of %s failed: %s\n", filename, msg);
+ }
+
+out:
+ return is_zlib_file;
+}
+
char *zlib_decompress_file(const char *filename, off_t *r_size)
{
gzFile fp;
@@ -84,6 +116,12 @@ fail:
return buf;
}
#else
+
+int is_zlib_file(const char *filename, off_t *r_size)
+{
+ return 0;
+}
+
char *zlib_decompress_file(const char *UNUSED(filename), off_t *UNUSED(r_size))
{
return NULL;
--
1.8.3.1

View File

@ -0,0 +1,36 @@
From 019d8258f15c2a716786880c3cbd0f327a4dfc09 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 15 Jul 2019 11:32:53 +0530
Subject: [PATCH 15/20] kexec/kexec.c: Add the missing close() for fd used for
kexec_file_load()
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=019d8258f15c2a716786880c3cbd0f327a4dfc09
In kexec/kexec.c, we open() the kernel Image file and pass this file
descriptor to the kexec_file_load() system call, but never call a
corresponding close().
Fix the same via this patch.
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/kexec.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 32ae56c..8ca3b45 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1234,6 +1234,8 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
if (ret != 0)
fprintf(stderr, "kexec_file_load failed: %s\n",
strerror(errno));
+
+ close(kernel_fd);
return ret;
}
--
1.8.3.1

View File

@ -0,0 +1,37 @@
From 35a2fb50293da9fbd94f29a2ed6a4f114fd8044f Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Tue, 21 Aug 2018 16:22:31 +0530
Subject: [PATCH] kexec: fix for "Unhandled rela relocation: R_X86_64_PLT32"
error
In response to a change in binutils, commit b21ebf2fb4c
(x86: Treat R_X86_64_PLT32 as R_X86_64_PC32) was applied to
the linux kernel during the 4.16 development cycle and has
since been backported to earlier stable kernel series. The
change results in the failure message in $SUBJECT when
rebooting via kexec.
Fix this by replicating the change in kexec.
Signed-off-by: Chris Clayton <chris2553@googlemail.com>
---
kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/x86_64/kexec-elf-rel-x86_64.c b/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
index 7fdde73a5eca..af33689a7d43 100644
--- a/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
+++ b/kexec/arch/x86_64/kexec-elf-rel-x86_64.c
@@ -78,7 +78,8 @@ void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
if ((int64_t)value != *(int32_t *)location)
goto overflow;
break;
- case R_X86_64_PC32:
+ case R_X86_64_PC32:
+ case R_X86_64_PLT32:
*(uint32_t *)location = value - address;
break;
default:
--
2.7.4

BIN
kexec-tools-2.0.17.tar.xz Normal file

Binary file not shown.

View File

@ -0,0 +1,31 @@
From 072c36f24d52f3c3c864ace33da675a8e5c009d8 Mon Sep 17 00:00:00 2001
From: Jialong Chen <chenjialong@huawei.com>
Date: Tue, 24 Oct 2017 17:10:21 +0800
Subject: [PATCH] kexec-tools: increase the buf space to 1536
reason: increase the buf space to 1536
Signed-off-by: Jialong Chen <chenjialong@huawei.com>
---
kexec/arch/arm64/kexec-arm64.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 7e4d056..0490d07 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -15,7 +15,10 @@
#define BOOT_BLOCK_VERSION 17
#define BOOT_BLOCK_LAST_COMP_VERSION 16
-#define COMMAND_LINE_SIZE 512
+/* kernel define COMMAND_LINE_SIZE 2048, kexec will append some parameter to follow command_line
+ * so we define COMMAND_LINE_SIZE 1024+512 here.
+*/
+#define COMMAND_LINE_SIZE 1536
#define KiB(x) ((x) * 1024UL)
#define MiB(x) (KiB(x) * 1024UL)
--
1.8.3.1

342
kexec-tools.spec Normal file
View File

@ -0,0 +1,342 @@
Name: kexec-tools
Version: 2.0.17
Release: 13
License: GPLv2
Summary: The kexec/kdump userspace component
URL: https://www.kernel.org/
Source0: http://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.xz
Source1: kdumpctl
Source2: kdump.sysconfig
Source3: kdump.sysconfig.x86_64
Source4: kdump.sysconfig.i386
Source5: kdump.sysconfig.ppc64
Source7: mkdumprd
Source8: kdump.conf
Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.4/makedumpfile-1.6.4.tar.gz
Source12: mkdumprd.8
Source14: 98-kexec.rules
Source15: kdump.conf.5
Source16: kdump.service
Source18: kdump.sysconfig.s390x
Source19: eppic_050615.tar.gz
Source20: kdump-lib.sh
Source21: kdump-in-cluster-environment.txt
Source22: kdump-dep-generator.sh
Source23: kdump-lib-initramfs.sh
Source24: kdump.sysconfig.ppc64le
Source25: kdumpctl.8
Source26: live-image-kdump-howto.txt
Source27: early-kdump-howto.txt
Source100: dracut-kdump.sh
Source101: dracut-module-setup.sh
Source102: dracut-monitor_dd_progress
Source103: dracut-kdump-error-handler.sh
Source104: dracut-kdump-emergency.service
Source105: dracut-kdump-error-handler.service
Source106: dracut-kdump-capture.service
Source107: dracut-kdump-emergency.target
Source108: dracut-early-kdump.sh
Source109: dracut-early-kdump-module-setup.sh
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
Requires(pre): coreutils sed zlib
Requires: dracut >= 047-34.git20180604
Requires: dracut-network >= 044-117
Requires: ethtool
BuildRequires: zlib-devel zlib zlib-static elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel
BuildRequires: pkgconfig intltool gettext
BuildRequires: systemd-units
BuildRequires: automake autoconf libtool
%ifarch %{ix86} x86_64
Obsoletes: diskdumputils netdump kexec-tools-eppic
%endif
%undefine _hardened_build
Patch101: kexec-tools-2.0.17-kexec-fix-for-Unhandled-rela-relocation-R_X86_64_PLT.patch
Patch6000: vmcore-dmesg-fix-infinite-loop-if-log-buffer-wraps-a.patch
Patch6001: arm64-error-out-if-kernel-command-line-is-too-long.patch
Patch6002: kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch
Patch6003: x86-fix-BAD_FREE-in-get_efi_runtime_map.patch
Patch6004: kexec-dt-ops.c-Fix-check-against-fdt_add_subnode-ret.patch
Patch6005: kexec-kexec-arm64.c-Add-error-handling-check-against.patch
Patch6006: kexec-dt-ops.c-Fix-adding-chosen-node-for-cases-wher.patch
Patch6007: kexec-dt-ops.c-Fix-chosen-v-s-chosen-node-being-pass.patch
Patch6008: arm64-wipe-old-initrd-addresses-when-patching-the-DT.patch
Patch6009: xen-Avoid-overlapping-segments-in-low-memory.patch
Patch6010: x86-Check-proc-mounts-before-mtab-for-mounts.patch
Patch6011: x86-Find-mounts-by-FS-type-not-name.patch
Patch6012: kexec-kexec.c-Add-the-missing-close-for-fd-used-for-kexec_file_load.patch
Patch6013: kexec-uImage-arm64.c-Fix-return-value-of-uImage_arm64_probe.patch
Patch6014: kexec-kexec-zlib.h-Add-is_zlib_file-helper-function.patch
Patch6015: kexec-arm64-Add-support-for-handling-zlib-compressed-image.patch
%ifarch aarch64
Patch9000: kexec-tools-2.0.8-increase-the-buf-space-to-1536.patch
Patch9001: bugfix-get-the-paddr-of-mem_section-return-error-address.patch
Patch9002: arm64-support-more-than-one-crash-kernel-regions.patch
%endif
Patch9003: makedumpfile-modify-SECTIONS_SIZE_BITS-to-27-for-arm.patch
Patch9004: add-secure-compile-options-for-makedumpfile.patch
%description
kexec-tools provides /sbin/kexec binary that facilitates a new
kernel to boot using the kernel's kexec feature either on a
normal or a panic reboot. This package contains the /sbin/kexec
binary and ancillary utilities that together form the userspace
component of the kernel's kexec feature.
%package help
Summary: Doc files for %{name}
Buildarch: noarch
%description help
The %{name}-help package contains doc files for %{name}.
%prep
%setup -q
mkdir -p -m755 kcp
tar -z -x -v -f %{SOURCE9}
tar -z -x -v -f %{SOURCE19}
%patch101 -p1
%{lua:for i=0,8 do print(string.format("%%patch600%u -p1\n", i)) end}
%patch6009 -p1
%patch6010 -p1
%patch6011 -p1
%patch6012 -p1
%patch6013 -p1
%patch6014 -p1
%patch6015 -p1
%ifarch aarch64
%{lua:for i=0,2 do print(string.format("%%patch900%u -p1\n", i)) end}
%endif
%patch9003 -p1
%patch9004 -p1
%build
autoreconf
%configure --sbindir=/sbin \
CFLAGS="${CFLAGS} -fstack-protector-strong -Wl,-z,now -pie -fPIC -fPIE"
rm -f kexec-tools.spec.in
# for docs
cp %{SOURCE21} %{SOURCE26} %{SOURCE27} .
make
%ifarch %{ix86} x86_64 aarch64
make -C eppic/libeppic
make -C makedumpfile-1.6.4 LINKTYPE=dynamic USELZO=on USESNAPPY=on
make -C makedumpfile-1.6.4 LDFLAGS="-I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so
%endif
%install
mkdir -p -m755 %{buildroot}/sbin
mkdir -p -m755 %{buildroot}%{_sysconfdir}/sysconfig
mkdir -p -m755 %{buildroot}%{_localstatedir}/crash
mkdir -p -m755 %{buildroot}%{_mandir}/man8/
mkdir -p -m755 %{buildroot}%{_mandir}/man5/
mkdir -p -m755 %{buildroot}%{_docdir}
mkdir -p -m755 %{buildroot}%{_datadir}/kdump
mkdir -p -m755 %{buildroot}%{_udevrulesdir}
mkdir -p %{buildroot}%{_unitdir}
mkdir -p -m755 %{buildroot}%{_bindir}
mkdir -p -m755 %{buildroot}%{_libdir}
mkdir -p -m755 %{buildroot}%{_prefix}/lib/kdump
install -m 755 %{SOURCE1} %{buildroot}%{_bindir}/kdumpctl
install -m 755 build/sbin/kexec %{buildroot}/sbin/kexec
install -m 755 build/sbin/vmcore-dmesg %{buildroot}/sbin/vmcore-dmesg
install -m 644 build/man/man8/kexec.8 %{buildroot}%{_mandir}/man8/
install -m 644 build/man/man8/vmcore-dmesg.8 %{buildroot}%{_mandir}/man8/
SYSCONFIG=%{_sourcedir}/kdump.sysconfig.%{_target_cpu}
[ -f $SYSCONFIG ] || SYSCONFIG=%{_sourcedir}/kdump.sysconfig.%{_arch}
[ -f $SYSCONFIG ] || SYSCONFIG=%{_sourcedir}/kdump.sysconfig
install -m 644 $SYSCONFIG %{buildroot}%{_sysconfdir}/sysconfig/kdump
install -m 755 %{SOURCE7} %{buildroot}/sbin/mkdumprd
install -m 644 %{SOURCE8} %{buildroot}%{_sysconfdir}/kdump.conf
install -m 644 kexec/kexec.8 %{buildroot}%{_mandir}/man8/kexec.8
install -m 644 %{SOURCE12} %{buildroot}%{_mandir}/man8/mkdumprd.8
install -m 644 %{SOURCE25} %{buildroot}%{_mandir}/man8/kdumpctl.8
install -m 755 %{SOURCE20} %{buildroot}%{_prefix}/lib/kdump/kdump-lib.sh
install -m 755 %{SOURCE23} %{buildroot}%{_prefix}/lib/kdump/kdump-lib-initramfs.sh
install -m 644 %{SOURCE15} %{buildroot}%{_mandir}/man5/kdump.conf.5
install -m 644 %{SOURCE16} %{buildroot}%{_unitdir}/kdump.service
install -m 755 -D %{SOURCE22} %{buildroot}%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
install -m 644 %{SOURCE14} %{buildroot}%{_udevrulesdir}/98-kexec.rules
%ifarch %{ix86} x86_64 aarch64
install -m 755 makedumpfile-1.6.4/makedumpfile %{buildroot}/sbin/makedumpfile
install -m 644 makedumpfile-1.6.4/makedumpfile.8.gz %{buildroot}/%{_mandir}/man8/makedumpfile.8.gz
install -m 644 makedumpfile-1.6.4/makedumpfile.conf.5.gz %{buildroot}/%{_mandir}/man5/makedumpfile.conf.5.gz
install -m 644 makedumpfile-1.6.4/makedumpfile.conf %{buildroot}/%{_sysconfdir}/makedumpfile.conf.sample
install -m 755 makedumpfile-1.6.4/eppic_makedumpfile.so %{buildroot}/%{_libdir}/eppic_makedumpfile.so
mkdir -p %{buildroot}/usr/share/makedumpfile/eppic_scripts/
install -m 644 makedumpfile-1.6.4/eppic_scripts/* %{buildroot}/usr/share/makedumpfile/eppic_scripts/
%endif
%define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g')
%define remove_dracut_early_kdump_prefix() %(echo -n %1|sed 's/.*dracut-early-kdump-//g')
# For dracut modules
mkdir -p -m755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase
cp %{SOURCE100} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}}
cp %{SOURCE101} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}}
cp %{SOURCE102} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE102}}
cp %{SOURCE103} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE103}}
cp %{SOURCE104} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE104}}
cp %{SOURCE105} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE105}}
cp %{SOURCE106} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE106}}
cp %{SOURCE107} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE107}}
chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}}
chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}}
mkdir -p -m755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump
cp %{SOURCE108} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix %{SOURCE108}}
cp %{SOURCE109} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}}
chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix %{SOURCE108}}
chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}}
%define dracutlibdir %{_prefix}/lib/dracut
# For custom dracut modules
mkdir -p %{buildroot}/%{dracutlibdir}/modules.d/
mv %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/* %{buildroot}/%{dracutlibdir}/modules.d/
%post
%systemd_post kdump.service
touch /etc/kdump.conf
# Fix up broken boxes
if [ -d /proc/bus/mckinley ]
then
# for HP zx1 machines
sed -e's/\(^KDUMP_COMMANDLINE_APPEND.*\)\("$\)/\1 machvec=dig"/' \
/etc/sysconfig/kdump > /etc/sysconfig/kdump.new
mv /etc/sysconfig/kdump.new /etc/sysconfig/kdump
elif [ -d /proc/sgi_sn ]
then
# for SGI SN boxes
sed -e's/\(^KEXEC_ARGS.*\)\("$\)/\1 --noio"/' \
/etc/sysconfig/kdump > /etc/sysconfig/kdump.new
mv /etc/sysconfig/kdump.new /etc/sysconfig/kdump
fi
%postun
%systemd_postun_with_restart kdump.service
%preun
%systemd_preun kdump.service
%triggerun -- kexec-tools < 2.0.2-3
# Save runlevel info for future migration
/usr/bin/systemd-sysv-convert --save kdump >/dev/null 2>&1 ||:
# Not needed after uninstall
/sbin/chkconfig --del kdump >/dev/null 2>&1 || :
/bin/systemctl try-restart kdump.service >/dev/null 2>&1 || :
%triggerin -- kernel-kdump
touch %{_sysconfdir}/kdump.conf
%triggerpostun -- kernel kernel-xen kernel-debug kernel-PAE kernel-kdump
# Search for kernel installs, if not found, remove kdump initrd
IMGDIR=/boot
for i in `ls $IMGDIR/initramfs*kdump.img 2>/dev/null`
do
KDVER=`echo $i | sed -e's/^.*initramfs-//' -e's/kdump.*$//'`
if [ ! -e $IMGDIR/vmlinuz-$KDVER ]
then
rm -f $i
fi
done
%files
%doc News
%doc TODO
%license COPYING
%config(noreplace,missingok) %{_sysconfdir}/sysconfig/kdump
%config(noreplace,missingok) %{_sysconfdir}/kdump.conf
%config %{_udevrulesdir}
%dir %{_localstatedir}/crash
/sbin/kexec
/sbin/mkdumprd
/sbin/vmcore-dmesg
%{_bindir}/*
%{_datadir}/kdump
%{_prefix}/lib/kdump
%{dracutlibdir}/modules.d/*
%{_unitdir}/kdump.service
%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
%ifarch %{ix86} x86_64 aarch64
%{_libdir}/eppic_makedumpfile.so
/usr/share/makedumpfile/
%endif
%ifarch %{ix86} x86_64 aarch64
%{_sysconfdir}/makedumpfile.conf.sample
%endif
%ifarch %{ix86} x86_64 aarch64
/sbin/makedumpfile
%endif
%files help
%doc early-kdump-howto.txt
%doc kdump-in-cluster-environment.txt
%doc live-image-kdump-howto.txt
%{_mandir}/man8/kdumpctl.8.gz
%{_mandir}/man8/kexec.8.gz
%{_mandir}/man8/mkdumprd.8.gz
%{_mandir}/man8/vmcore-dmesg.8.gz
%{_mandir}/man5/*
%ifarch %{ix86} x86_64 aarch64
%{_mandir}/man8/makedumpfile.8.gz
%endif
%changelog
* Thu Dec 19 2019 chengquan <chengquan3@huawei.com> - 2.0.17-13
- Type:enhancement
- ID:NA
- SUG:NA
- DESC:add url for package
* Wed Sep 25 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.0-17.12
- add secure compile options and merge bugfix patches from community
xen: Avoid overlapping segments in low memory
x86: Check /proc/mounts before mtab for mounts
x86: Find mounts by FS type, not name
kexec/kexec.c: Add the missing close() for fd used for kexec_file_load()
kexec-uImage-arm64.c: Fix return value of uImage_arm64_probe()
kexec/kexec-zlib.h: Add 'is_zlib_file()' helper function
kexec/arm64: Add support for handling zlib compressed (Image.gz) image
* Thu Sep 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.0-17.11
- Package init
* Thu Aug 22 2019 Yeqing Peng<pengyeqing@huawei.com> - 2.0-17.10.h1
- Type:bugfix
- ID:NA
- SUG:restart
- DESC: fix bugs as follows:
1.dmesg fix infinite loop if log buffer wraps around.
2.arm64 error out if kernel command line is too long.
3.fix an error that can not parse the e820 reserved region.
4.x86 fix BAD_FREE in get_efi_runtime_map().
5.fix check against 'fdt_add_subnode' return value.
6.arm64 add error handling check against return value of 'set_bootargs()'.
7.fix adding '/chosen' node for cases where it is not available in dtb
passed via --dtb option.
8.fix '/chosen' v/s 'chosen' node being passed to fdt helper functions.
9.arm64 wipe old initrd addresses when patching the DTB.
10.arm64 increase the command line buf space to 1536.
11.arm64 bugfix get the paddr of mem_section return error address.
12.arm64 support more than one crash kernel regions.
13.modify SECTIONS_SIZE_BITS to 27 for arm64.

View File

@ -0,0 +1,57 @@
From 6ef59c03bf2c42f6577c708b58598868e8e8fb0b Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Mon, 15 Jul 2019 11:32:54 +0530
Subject: [PATCH 16/20] kexec-uImage-arm64.c: Fix return value of
uImage_arm64_probe()
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=6ef59c03bf2c42f6577c708b58598868e8e8fb0b
Commit bf06cf2095e1 ("kexec/uImage: probe to identify a corrupted image"),
defined the 'uImage_probe_kernel()' function return values and
correspondingly ;uImage_arm64_probe()' returns the same (0 -> If the
image is valid 'type' image, -1 -> If the image is corrupted and
1 -> If the image is not a uImage).
This causes issues because, in later patches we introduce zImage
support for arm64, and since it is probed after uImage, the return
values from 'uImage_arm64_probe()' needs to be fixed to make sure
that kexec will not return with an invalid error code.
Now, 'uImage_arm64_probe()' returns the following values instead:
0 - valid uImage.
-1 - uImage is corrupted.
1 - image is not a uImage.
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-uImage-arm64.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/arm64/kexec-uImage-arm64.c b/kexec/arch/arm64/kexec-uImage-arm64.c
index 126ea9c..c466913 100644
--- a/kexec/arch/arm64/kexec-uImage-arm64.c
+++ b/kexec/arch/arm64/kexec-uImage-arm64.c
@@ -11,7 +11,18 @@
int uImage_arm64_probe(const char *buf, off_t len)
{
- return uImage_probe_kernel(buf, len, IH_ARCH_ARM64);
+ int ret;
+
+ ret = uImage_probe_kernel(buf, len, IH_ARCH_ARM64);
+
+ /* 0 - valid uImage.
+ * -1 - uImage is corrupted.
+ * 1 - image is not a uImage.
+ */
+ if (!ret)
+ return 0;
+ else
+ return -1;
}
int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len,
--
1.8.3.1

View File

@ -0,0 +1,25 @@
Kdump now works on live images with some manual configurations. Here is the step
by step guide.
1. Enable crashkernel reservation
Since there isn't any config file that can be used to configure kernel
parameters for live images before booting them, we have to append 'crashkernel'
argument in boot menu every time we boot a live image.
2. Change dump target in /etc/kdump.conf
When kdump kernel boots in a live environment, the default target /var/crash is
in RAM so you need to change the dump target to an external disk or a network
dump target.
Besides, make sure that "default dump_to_rootfs" is not specified.
3. Start kdump service
$ kdumpctl start
4. Trigger a kdump test
$ echo 1 > /proc/sys/kernel/sysrq
$ echo c > /proc/sysrq-trigger

BIN
makedumpfile-1.6.4.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,28 @@
From 2aa3a429d035e9549b25efe06b06503d60a845c8 Mon Sep 17 00:00:00 2001
From: YunFeng Ye <yeyunfeng@huawei.com>
Date: Thu, 4 Jul 2019 00:05:35 +0800
Subject: [PATCH] kexec-tools: modify SECTIONS_SIZE_BITS to 27 for arm64
reason: modify SECTIONS_SIZE_BITS to 27 for arm64
Signed-off-by: YunFeng Ye <yeyunfeng@huawei.com>
---
arch/arm64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64.c b/arch/arm64.c
index 2fd3e18..749ff2e 100644
--- a/makedumpfile-1.6.4/arch/arm64.c
+++ b/makedumpfile-1.6.4/arch/arm64.c
@@ -73,7 +73,7 @@ static unsigned long kimage_voffset;
#define PTRS_PER_PMD PTRS_PER_PTE
#define PAGE_PRESENT (1 << 0)
-#define SECTIONS_SIZE_BITS 30
+#define SECTIONS_SIZE_BITS 27
/* Highest possible physical address supported */
#define PHYS_MASK_SHIFT 48
#define PHYS_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
--
1.8.3.1

466
mkdumprd Normal file
View File

@ -0,0 +1,466 @@
#!/bin/bash --norc
# New mkdumprd
#
# Copyright 2011 Red Hat, Inc.
#
# Written by Cong Wang <amwang@redhat.com>
#
[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
. $dracutbasedir/dracut-functions.sh
. /lib/kdump/kdump-lib.sh
export IN_KDUMP=1
conf_file="/etc/kdump.conf"
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
SAVE_PATH=$(grep ^path $conf_file| cut -d' ' -f2)
[ -z "$SAVE_PATH" ] && SAVE_PATH=$DEFAULT_PATH
# strip the duplicated "/"
SAVE_PATH=$(echo $SAVE_PATH | tr -s /)
is_wdt_addition_needed() {
local active
is_wdt_mod_omitted
[[ $? -eq 0 ]] && return 1
[[ -d /sys/class/watchdog/ ]] || return 1
for dir in /sys/class/watchdog/*; do
[[ -f "$dir/state" ]] || continue
active=$(< "$dir/state")
[[ "$active" = "active" ]] && return 0
done
return 1
}
WDTCFG=""
is_wdt_addition_needed
[[ $? -eq 0 ]] && WDTCFG="-a watchdog"
extra_modules=""
dracut_args=("--quiet" "--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg" $WDTCFG)
OVERRIDE_RESETTABLE=0
add_dracut_arg() {
local arg qarg is_quoted=0
while [ $# -gt 0 ];
do
arg="${1//\'/\"}"
#Handle quoted substring properly for passing it to dracut_args array.
if [ $is_quoted -eq 0 ]; then
if [[ "$arg" == "\"" ]] || [[ $arg != ${arg#\"} ]]; then
is_quoted=1
arg=${arg#\"}
fi
fi
if [ $is_quoted -eq 1 ]; then
qarg="$qarg $arg"
if [[ "$arg" == "\"" ]] || [[ $arg != ${arg%\"} ]]; then
is_quoted=0
arg=${qarg%\"}
qarg=""
else
shift
continue
fi
fi
dracut_args+=("$arg")
shift
done
}
add_dracut_module() {
add_dracut_arg "--add" "$1"
}
add_dracut_mount() {
add_dracut_arg "--mount" "$1"
}
add_dracut_sshkey() {
add_dracut_arg "--sshkey" "$1"
}
# caller should ensure $1 is valid and mounted in 1st kernel
to_mount() {
local _dev=$1 _source _target _fstype _options _mntopts _pdev
_source=$(findmnt -k -f -n -r -o SOURCE $_dev)
_target=$(get_mntpoint_from_target $_dev)
# mount under /sysroot if dump to root disk or mount under
#/kdumproot/$_target in other cases in 2nd kernel. systemd
#will be in charge to umount it.
if [ "$_target" = "/" ];then
_target="/sysroot"
else
_target="/kdumproot/$_target"
fi
_fstype=$(findmnt -k -f -n -r -o FSTYPE $_dev)
[[ -e /etc/fstab ]] && _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev)
[ -z "$_options" ] && _options=$(findmnt -k -f -n -r -o OPTIONS $_dev)
# with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd
# kernel, filter it out here.
_options=$(echo $_options | sed 's/\bnoauto\b//')
#mount fs target as rw in 2nd kernel
_options=$(echo $_options | sed 's/\bro\b/rw/')
# drop nofail or nobootwait
_options=$(echo $_options | sed 's/\bnofail\b//')
_options=$(echo $_options | sed 's/\bnobootwait\b//')
_mntopts="$_target $_fstype $_options"
#for non-nfs _dev converting to use udev persistent name
if [ -b "$_source" ]; then
_pdev="$(get_persistent_dev $_source)"
if [ -z "$_pdev" ]; then
return 1
fi
else
_pdev=$_dev
fi
echo "$_pdev $_mntopts"
}
is_readonly_mount() {
local _mnt
_mnt=$(findmnt -k -f -n -r -o OPTIONS $1)
#fs/proc_namespace.c: show_mountinfo():
#seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
[[ "$_mnt" =~ ^ro ]]
}
#Function: get_ssh_size
#$1=dump target
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
get_ssh_size() {
local _opt _out _size
_opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
_out=$(ssh -q -n $_opt $1 "df -P $SAVE_PATH")
[ $? -ne 0 ] && {
perror_exit "checking remote ssh server available size failed."
}
#ssh output removed the line break, so print field NF-2
_size=$(echo -n $_out| awk '{avail=NF-2; print $avail}')
echo -n $_size
}
#mkdir if save path does not exist on ssh dump target
#$1=ssh dump target
#caller should ensure write permission on $DUMP_TARGET:$SAVE_PATH
#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
mkdir_save_path_ssh()
{
local _opt _dir
_opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null
_ret=$?
if [ $_ret -ne 0 ]; then
perror_exit "mkdir failed on $DUMP_TARGET:$SAVE_PATH"
fi
#check whether user has write permission on $SAVE_PATH/$DUMP_TARGET
_dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null)
_ret=$?
if [ $_ret -ne 0 ]; then
perror_exit "Could not create temporary directory on $DUMP_TARGET:$SAVE_PATH. Make sure user has write permission on destination"
fi
ssh -qn $_opt $1 rmdir $_dir
return 0
}
#Function: get_fs_size
#$1=dump target
get_fs_size() {
local _mnt=$(get_mntpoint_from_target $1)
echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}')
}
#Function: get_raw_size
#$1=dump target
get_raw_size() {
echo -n $(fdisk -s "$1")
}
#Function: check_size
#$1: dump type string ('raw', 'fs', 'ssh')
#$2: dump target
check_size() {
local avail memtotal
memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
case "$1" in
raw)
avail=$(get_raw_size "$2")
;;
ssh)
avail=$(get_ssh_size "$2")
;;
fs)
avail=$(get_fs_size "$2")
;;
*)
return
esac
if [ $? -ne 0 ]; then
perror_exit "Check dump target size failed"
fi
if [ $avail -lt $memtotal ]; then
echo "Warning: There might not be enough space to save a vmcore."
echo " The size of $2 should be greater than $memtotal kilo bytes."
fi
}
# $1: core_collector config value
verify_core_collector() {
if grep -q "^raw" $conf_file && [ "${1%% *}" != "makedumpfile" ]; then
echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
fi
if is_ssh_dump_target || is_raw_dump_target; then
if [ "${1%% *}" = "makedumpfile" ]; then
! strstr "$1" "-F" && {
perror_exit "The specified dump target needs makedumpfile \"-F\" option."
}
fi
fi
}
add_mount() {
local _mnt=$(to_mount "$1")
if [ $? -ne 0 ]; then
exit 1
fi
add_dracut_mount "$_mnt"
}
#handle the case user does not specify the dump target explicitly
handle_default_dump_target()
{
local _target
local _mntpoint
is_user_configured_dump_target && return
check_save_path_fs $SAVE_PATH
_mntpoint=$(get_mntpoint_from_path $SAVE_PATH)
_target=$(get_target_from_path $SAVE_PATH)
if is_atomic && is_bind_mount $_mntpoint; then
SAVE_PATH=${SAVE_PATH##"$_mntpoint"}
# the real dump path in the 2nd kernel, if the mount point is bind mounted.
SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH
_mntpoint=$(get_mntpoint_from_target $_target)
# the absolute path in the 1st kernel
SAVE_PATH=$_mntpoint/$SAVE_PATH
fi
SAVE_PATH=${SAVE_PATH##"$_mntpoint"}
add_mount "$_target"
check_size fs $_target
}
get_override_resettable()
{
local override_resettable
override_resettable=$(grep "^override_resettable" $conf_file)
if [ -n "$override_resettable" ]; then
OVERRIDE_RESETTABLE=$(echo $override_resettable | cut -d' ' -f2)
if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ];then
perror_exit "override_resettable value $OVERRIDE_RESETTABLE is invalid"
fi
fi
}
# $1: function name
for_each_block_target()
{
local dev majmin
for dev in $(get_kdump_targets); do
[ -b "$dev" ] || continue
majmin=$(get_maj_min $dev)
check_block_and_slaves $1 $majmin && return 1
done
return 0
}
#judge if a specific device with $1 is unresettable
#return false if unresettable.
is_unresettable()
{
local path="/sys/$(udevadm info --query=all --path=/sys/dev/block/$1 | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable"
local resettable=1
if [ -f "$path" ]
then
resettable="$(cat $path)"
[ $resettable -eq 0 -a "$OVERRIDE_RESETTABLE" -eq 0 ] && {
local device=$(udevadm info --query=all --path=/sys/dev/block/$1 | awk -F= '/DEVNAME/{print $2}')
echo "Error: Can not save vmcore because device $device is unresettable"
return 0
}
fi
return 1
}
#check if machine is resettable.
#return true if resettable
check_resettable()
{
local _ret _target
get_override_resettable
for_each_block_target is_unresettable
_ret=$?
[ $_ret -eq 0 ] && return
return 1
}
# $1: maj:min
is_crypt()
{
local majmin=$1 dev line ID_FS_TYPE=""
line=$(udevadm info --query=property --path=/sys/dev/block/$majmin \
| grep "^ID_FS_TYPE")
eval "$line"
[[ "$ID_FS_TYPE" = "crypto_LUKS" ]] && {
dev=$(udevadm info --query=all --path=/sys/dev/block/$majmin | awk -F= '/DEVNAME/{print $2}')
echo "Device $dev is encrypted."
return 0
}
return 1
}
check_crypt()
{
local _ret _target
for_each_block_target is_crypt
_ret=$?
[ $_ret -eq 0 ] && return
return 1
}
if ! check_resettable; then
exit 1
fi
if ! check_crypt; then
echo "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot."
fi
# firstly get right SSH_KEY_LOCATION
keyfile=$(awk '/^sshkey/ {print $2}' $conf_file)
if [ -f "$keyfile" ]; then
# canonicalize the path
SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile)
fi
if [ "$(uname -m)" = "s390x" ]; then
add_dracut_module "znet"
fi
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
config_val=$(strip_comments $config_val)
case "$config_opt" in
extra_modules)
extra_modules="$extra_modules $config_val"
;;
ext[234]|xfs|btrfs|minix|nfs)
if ! findmnt $config_val >/dev/null; then
perror_exit "Dump target $config_val is probably not mounted."
fi
_absolute_save_path=$(make_absolute_save_path $config_val)
_mntpoint=$(get_mntpoint_from_path $_absolute_save_path)
if is_atomic && is_bind_mount $_mntpoint; then
SAVE_PATH=${_absolute_save_path##"$_mntpoint"}
# the real dump path in the 2nd kernel, if the mount point is bind mounted.
SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH
fi
add_mount "$config_val"
check_save_path_fs $_absolute_save_path
check_size fs $config_val
;;
raw)
#checking raw disk writable
dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || {
perror_exit "Bad raw disk $config_val"
}
_praw=$(persistent_policy="by-id" get_persistent_dev $config_val)
if [ -z "$_praw" ]; then
exit 1
fi
add_dracut_arg "--device" "$_praw"
check_size raw $config_val
;;
ssh)
if strstr "$config_val" "@";
then
check_size ssh $config_val
mkdir_save_path_ssh $config_val
add_dracut_module "ssh-client"
add_dracut_sshkey "$SSH_KEY_LOCATION"
else
perror_exit "Bad ssh dump target $config_val"
fi
;;
core_collector)
verify_core_collector "$config_val"
;;
dracut_args)
add_dracut_arg $config_val
;;
*)
if [ -n $(echo $config_opt | grep "^#.*$") ]
then
continue
fi
;;
esac
done < $conf_file
handle_default_dump_target
if [ -n "$extra_modules" ]
then
add_dracut_arg "--add-drivers" "$extra_modules"
fi
if ! is_fadump_capable; then
# The 2nd rootfs mount stays behind the normal dump target mount,
# so it doesn't affect the logic of check_dump_fs_modified().
is_dump_to_rootfs && add_mount "$(to_dev_name $(get_root_fs_device))"
add_dracut_arg "--no-hostonly-default-device"
fi
dracut "${dracut_args[@]}" "$@"
_rc=$?
sync
exit $_rc

33
mkdumprd.8 Normal file
View File

@ -0,0 +1,33 @@
.TH MKDUMRD 8 "Fri Feb 9 2007"
.SH NAME
mkdumprd \- creates initial ramdisk images for kdump crash recovery
.SH SYNOPSIS
\fBmkdumprd\fR [OPTION]
.SH DESCRIPTION
\fBmkdumprd\fR creates an initial ram file system for use in conjunction with
the booting of a kernel within the kdump framework for crash recovery.
\fBmkdumprds\fR purpose is to create an initial ram filesystem capable of copying
the crashed systems vmcore image to a location specified in \fI/etc/kdump.conf
\fBmkdumprd\fR interrogates the running system to understand what modules need to
be loaded in the initramfs (based on configuration retrieved from
\fI/etc/kdump.conf)\fR
\fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR
utility to generate the initramfs.
\fBmkdumprd\fR was not intended for casual use outside of the service
initialization script for the kdump utility, and should not be run manually. If
you require a custom kdump initramfs image, it is suggested that you use the
kdump service infrastructure to create one, and then manually unpack, modify and
repack the image.
.SH OPTIONS
.TP
All options here are passed to dracut directly, please refer \fBdracut\fR docs
for the info.
.SH "SEE ALSO"
.BR dracut (8)

View File

@ -0,0 +1,37 @@
From e277fa9ec702fea7bd3135393c67327c821d5a3a Mon Sep 17 00:00:00 2001
From: Omar Sandoval <osandov@fb.com>
Date: Wed, 23 May 2018 13:59:31 -0700
Subject: [PATCH 08/37] vmcore-dmesg: fix infinite loop if log buffer wraps
around
We hit a bug where vmcore-dmesg would get stuck in a loop, and since we
were redirecting the output to a file, it wouldn't stop until it filled
up the disk. This only happened when the dmesg buffer had filled up and
wrapped around. It turns out that when we hit the end of the buffer, we
are looping back to the first record instead of the beginning of the
buffer, which will always loop forever.
Fixes: e08d26b3b7f1 ("vmcore-dmesg: avoid allocating large memory chunk for log buf")
Signed-off-by: Omar Sandoval <osandov@fb.com>
Acked-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
vmcore-dmesg/vmcore-dmesg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
index e340ef4..7972788 100644
--- a/vmcore-dmesg/vmcore-dmesg.c
+++ b/vmcore-dmesg/vmcore-dmesg.c
@@ -689,7 +689,7 @@ static void dump_dmesg_structured(int fd)
*/
loglen = struct_val_u16(buf, log_offset_len);
if (!loglen)
- current_idx = log_first_idx;
+ current_idx = 0;
else
/* Move to next record */
current_idx += loglen;
--
2.6.4.windows.1

View File

@ -0,0 +1,70 @@
From 23aaa44614a02d2184951142125cb55b36cef40a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= <mail@nh2.me>
Date: Mon, 29 Apr 2019 10:22:26 +0200
Subject: [PATCH 04/20] x86: Check /proc/mounts before mtab for mounts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=23aaa44614a02d2184951142125cb55b36cef40a
In many situations, especially on read-only file systems
and initial ramdisks (intramfs/initrd), /etc/mtab does not exist.
Before this commit, kexec would fail to read mounts on such systems
in `find_mnt_by_fsname()`, such that `get_bootparam()` would not
`boot_params/data`, which would then lead to e.g. `setup_efi_data()`
not being called in `setup_efi_info()`.
As a result, kexec'ed kernels would not obtain EFI data,
subsequentially lack an `ACPI RSDP` entry, emitting:
ACPI BIOS Error (bug): A valid RSDP was not found (20180810/tbxfroot-210)
and thus fail to turn off the machine on poweroff, instead printing only:
reboot: System halted
This problem had to be worked around by passing `acpi_rsdp=` manually
before. This commit obviates this workaround.
See also:
* https://github.com/coreos/bugs/issues/167#issuecomment-487320879
* http://lists.infradead.org/pipermail/kexec/2012-October/006924.html
Signed-off-by: Niklas Hambüchen <mail@nh2.me>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/i386/x86-linux-setup.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 8fad115..74fb0c4 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -432,7 +432,7 @@ out:
/*
* This really only makes sense for virtual filesystems that are only expected
* to be mounted once (sysfs, debugsfs, proc), as it will return the first
- * instance listed in mtab.
+ * instance listed in /proc/mounts, falling back to mtab if absent.
*/
char *find_mnt_by_fsname(char *fsname)
{
@@ -440,7 +440,11 @@ char *find_mnt_by_fsname(char *fsname)
struct mntent *mnt;
char *mntdir;
- mtab = setmntent("/etc/mtab", "r");
+ mtab = setmntent("/proc/mounts", "r");
+ if (!mtab) {
+ // Fall back to mtab
+ mtab = setmntent("/etc/mtab", "r");
+ }
if (!mtab)
return NULL;
for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) {
--
1.8.3.1

View File

@ -0,0 +1,84 @@
From c072bd13abbe497d28e4235e2cf416f4aee65754 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= <mail@nh2.me>
Date: Mon, 29 Apr 2019 10:23:14 +0200
Subject: [PATCH 05/20] x86: Find mounts by FS type, not name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=c072bd13abbe497d28e4235e2cf416f4aee65754
The name in mount invocations like
mount -t debugfs debugfs /sys/kernel/debug
is nothing but convention and cannot be relied upon.
For example, https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
recommends making the name "none" instead:
mount -t debugfs none /sys/kernel/debug
and many existing systems use mounts named "none" or otherwise.
Using `mnt_type` instead of `mnt_fsname` allows kexec to work
on such systems.
This fixes another instance of `poweroff` not working on kexec'ed
kernels because the lack of correctly matched mount results in EFI
variables not being read and propagated.
Signed-off-by: Niklas Hambüchen <mail@nh2.me>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/i386/x86-linux-setup.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 74fb0c4..b643c8b 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -433,8 +433,12 @@ out:
* This really only makes sense for virtual filesystems that are only expected
* to be mounted once (sysfs, debugsfs, proc), as it will return the first
* instance listed in /proc/mounts, falling back to mtab if absent.
+ * We search by type and not by name because the name can be anything;
+ * while setting the name equal to the mount point is common, it cannot be
+ * relied upon, as even kernel documentation examples recommends using
+ * "none" as the name e.g. for debugfs.
*/
-char *find_mnt_by_fsname(char *fsname)
+char *find_mnt_by_type(char *type)
{
FILE *mtab;
struct mntent *mnt;
@@ -448,7 +452,7 @@ char *find_mnt_by_fsname(char *fsname)
if (!mtab)
return NULL;
for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) {
- if (strcmp(mnt->mnt_fsname, fsname) == 0)
+ if (strcmp(mnt->mnt_type, type) == 0)
break;
}
mntdir = mnt ? strdup(mnt->mnt_dir) : NULL;
@@ -463,7 +467,7 @@ static int get_bootparam(void *buf, off_t offset, size_t size)
char filename[PATH_MAX];
int err, has_sysfs_params = 0;
- sysfs_mnt = find_mnt_by_fsname("sysfs");
+ sysfs_mnt = find_mnt_by_type("sysfs");
if (sysfs_mnt) {
snprintf(filename, PATH_MAX, "%s/%s", sysfs_mnt,
"kernel/boot_params/data");
@@ -474,7 +478,7 @@ static int get_bootparam(void *buf, off_t offset, size_t size)
}
if (!has_sysfs_params) {
- debugfs_mnt = find_mnt_by_fsname("debugfs");
+ debugfs_mnt = find_mnt_by_type("debugfs");
if (!debugfs_mnt)
return 1;
snprintf(filename, PATH_MAX, "%s/%s", debugfs_mnt,
--
1.8.3.1

View File

@ -0,0 +1,32 @@
From 8db8b6613a00e736e450401cff6121ec550a72f5 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Mon, 22 Oct 2018 15:54:16 +0800
Subject: [PATCH 53/55] x86: fix BAD_FREE in get_efi_runtime_map()
If the err_out label is reached, address of a stack variable is passed to
free(). Fix it.
Signed-off-by: Pingfan Liu <piliu@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/i386/x86-linux-setup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 6c7d260..6cda12c 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -595,8 +595,8 @@ static int get_efi_runtime_map(struct efi_mem_descriptor **map)
closedir(dirp);
return nr_maps;
err_out:
- if (map)
- free(map);
+ if (*map)
+ free(*map);
closedir(dirp);
return 0;
}
--
1.8.3.1

View File

@ -0,0 +1,153 @@
From eff53089523c331ac946df74ba365072a6fd1a95 Mon Sep 17 00:00:00 2001
From: David Woodhouse <dwmw@amazon.co.uk>
Date: Sun, 28 Apr 2019 13:52:12 +0300
Subject: [PATCH 03/20] xen: Avoid overlapping segments in low memory
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=eff53089523c331ac946df74ba365072a6fd1a95
Unlike Linux which creates a full identity mapping, Xen only maps those
segments which are explicitly requested. Therefore, xen_kexec_load()
silently adds in a segment from zero to 1MiB to ensure that VGA memory
and other things are accessible.
However, this doesn't work when there are already segments to be loaded
under 1MiB, because the overlap causes Xen to reject the kexec_load.
Be more careful and just infill the ranges which are required instead
of naïvely adding a full 0-1MiB segment at the end of the list.
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/kexec-xen.c | 73 ++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 54 insertions(+), 19 deletions(-)
diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c
index 1887390..c326955 100644
--- a/kexec/kexec-xen.c
+++ b/kexec/kexec-xen.c
@@ -64,15 +64,18 @@ int __xc_interface_close(xc_interface *xch)
}
#endif /* CONFIG_LIBXENCTRL_DL */
+#define IDENTMAP_1MiB (1024 * 1024)
+
int xen_kexec_load(struct kexec_info *info)
{
- uint32_t nr_segments = info->nr_segments;
+ uint32_t nr_segments = info->nr_segments, nr_low_segments = 0;
struct kexec_segment *segments = info->segment;
+ uint64_t low_watermark = 0;
xc_interface *xch;
xc_hypercall_buffer_array_t *array = NULL;
uint8_t type;
uint8_t arch;
- xen_kexec_segment_t *xen_segs;
+ xen_kexec_segment_t *xen_segs, *seg;
int s;
int ret = -1;
@@ -80,7 +83,28 @@ int xen_kexec_load(struct kexec_info *info)
if (!xch)
return -1;
- xen_segs = calloc(nr_segments + 1, sizeof(*xen_segs));
+ /*
+ * Ensure 0 - 1 MiB is mapped and accessible by the image.
+ * This allows access to the VGA memory and the region
+ * purgatory copies in the crash case.
+ *
+ * First, count the number of additional segments which will
+ * need to be added in between the ones in segments[].
+ *
+ * The segments are already sorted.
+ */
+ for (s = 0; s < nr_segments && (uint64_t)segments[s].mem <= IDENTMAP_1MiB; s++) {
+ if ((uint64_t)segments[s].mem > low_watermark)
+ nr_low_segments++;
+
+ low_watermark = (uint64_t)segments[s].mem + segments[s].memsz;
+ }
+ if (low_watermark < IDENTMAP_1MiB)
+ nr_low_segments++;
+
+ low_watermark = 0;
+
+ xen_segs = calloc(nr_segments + nr_low_segments, sizeof(*xen_segs));
if (!xen_segs)
goto out;
@@ -88,32 +112,43 @@ int xen_kexec_load(struct kexec_info *info)
if (array == NULL)
goto out;
+ seg = xen_segs;
for (s = 0; s < nr_segments; s++) {
DECLARE_HYPERCALL_BUFFER(void, seg_buf);
+ if (low_watermark < IDENTMAP_1MiB && (uint64_t)segments[s].mem > low_watermark) {
+ set_xen_guest_handle(seg->buf.h, HYPERCALL_BUFFER_NULL);
+ seg->buf_size = 0;
+ seg->dest_maddr = low_watermark;
+ low_watermark = (uint64_t)segments[s].mem;
+ if (low_watermark > IDENTMAP_1MiB)
+ low_watermark = IDENTMAP_1MiB;
+ seg->dest_size = low_watermark - seg->dest_maddr;
+ seg++;
+ }
+
seg_buf = xc_hypercall_buffer_array_alloc(xch, array, s,
seg_buf, segments[s].bufsz);
if (seg_buf == NULL)
goto out;
memcpy(seg_buf, segments[s].buf, segments[s].bufsz);
- set_xen_guest_handle(xen_segs[s].buf.h, seg_buf);
- xen_segs[s].buf_size = segments[s].bufsz;
- xen_segs[s].dest_maddr = (uint64_t)segments[s].mem;
- xen_segs[s].dest_size = segments[s].memsz;
+ set_xen_guest_handle(seg->buf.h, seg_buf);
+ seg->buf_size = segments[s].bufsz;
+ seg->dest_maddr = (uint64_t)segments[s].mem;
+ seg->dest_size = segments[s].memsz;
+ seg++;
+
+ low_watermark = (uint64_t)segments[s].mem + segments[s].memsz;
}
- /*
- * Ensure 0 - 1 MiB is mapped and accessible by the image.
- *
- * This allows access to the VGA memory and the region
- * purgatory copies in the crash case.
- */
- set_xen_guest_handle(xen_segs[s].buf.h, HYPERCALL_BUFFER_NULL);
- xen_segs[s].buf_size = 0;
- xen_segs[s].dest_maddr = 0;
- xen_segs[s].dest_size = 1 * 1024 * 1024;
- nr_segments++;
+ if ((uint64_t)low_watermark < IDENTMAP_1MiB) {
+ set_xen_guest_handle(seg->buf.h, HYPERCALL_BUFFER_NULL);
+ seg->buf_size = 0;
+ seg->dest_maddr = low_watermark;
+ seg->dest_size = IDENTMAP_1MiB - low_watermark;
+ seg++;
+ }
type = (info->kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH
: KEXEC_TYPE_DEFAULT;
@@ -125,7 +160,7 @@ int xen_kexec_load(struct kexec_info *info)
#endif
ret = xc_kexec_load(xch, type, arch, (uint64_t)info->entry,
- nr_segments, xen_segs);
+ nr_segments + nr_low_segments, xen_segs);
out:
xc_hypercall_buffer_array_destroy(xch, array);
--
1.8.3.1