import kexec-tools-2.0.24-1.el8

This commit is contained in:
CentOS Sources 2022-05-11 04:11:01 +00:00 committed by Stepan Oksanichenko
parent dbf4d4a69b
commit 3244c72eda
30 changed files with 110 additions and 2759 deletions

4
.gitignore vendored
View File

@ -1,3 +1,3 @@
SOURCES/1.7.0.tar.gz
SOURCES/1.7.1.tar.gz
SOURCES/eppic_050615.tar.gz
SOURCES/kexec-tools-2.0.20.tar.xz
SOURCES/kexec-tools-2.0.24.tar.xz

View File

@ -1,3 +1,3 @@
a931a40b80df204be1b02bfb502921cc618810fd SOURCES/1.7.0.tar.gz
8f8485c2a1edbc730f4fa1b96ae3ec8d8f1f9761 SOURCES/1.7.1.tar.gz
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz
62b7a99779d66ffd07a1684f7b640d32c9697f0c SOURCES/kexec-tools-2.0.24.tar.xz

View File

@ -110,6 +110,7 @@ rebuild_fadump_initrd()
return 1
fi
sync -f "$TARGET_INITRD"
return 0
}
@ -132,6 +133,7 @@ rebuild_kdump_initrd()
dwarn "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump."
fi
sync -f "$TARGET_INITRD"
return 0
}
@ -214,7 +216,7 @@ restore_default_initrd()
mv $DEFAULT_INITRD_BAK $DEFAULT_INITRD
if [[ $? -eq 0 ]]; then
derror "Restoring original initrd as fadump mode is disabled."
sync
sync -f "DEFAULT_INITRD"
fi
fi
fi

View File

@ -1,191 +0,0 @@
commit feae3d1754d2b0788ce1f18b0cd4b40098ff52ff
Author: Philipp Rudo <prudo@redhat.com>
Date: Mon Mar 14 17:04:29 2022 +0100
[PATCH v2 1/3] add generic cycle detection
In order to work makedumpfile needs to interpret data read from the
dump. This can cause problems as the data from the dump cannot be
trusted (otherwise the kernel wouldn't have panicked in the first
place). This also means that every loop which stop condition depend on
data read from the dump has a chance to loop forever. Thus add a generic
cycle detection mechanism that allows to detect and handle such
situations appropriately.
For cycle detection use Brent's algorithm [1] as it has constant memory
usage. With this it can also be used in the kdump kernel without the
danger that it runs oom when iterating large data structures.
Furthermore it only depends on some pointer arithmetic. Thus the
performance impact (as long as no cycle was detected) should be
comparatively small.
[1] https://en.wikipedia.org/wiki/Cycle_detection#Brent's_algorithm
Suggested-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Reviewed-and-tested-by: Dave Wysochanski <dwysocha@redhat.com>
diff --git a/makedumpfile-1.7.0/Makefile b/makedumpfile-1.7.0/Makefile
index f118b31e45989d9590ae075fb9b8ed2f27353a92..3441364cb6c7103a20072bd50ec58f1eed01ab69 100644
--- a/makedumpfile-1.7.0/Makefile
+++ b/makedumpfile-1.7.0/Makefile
@@ -45,7 +45,7 @@ CFLAGS_ARCH += -m32
endif
SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h
-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c
+SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c detect_cycle.c
OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART))
SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c arch/mips64.c
OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
diff --git a/makedumpfile-1.7.0/detect_cycle.c b/makedumpfile-1.7.0/detect_cycle.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b551a75d1c83d64fba2c078be8133efbc791fbe
--- /dev/null
+++ b/makedumpfile-1.7.0/detect_cycle.c
@@ -0,0 +1,99 @@
+/*
+ * detect_cycle.c -- Generic cycle detection using Brent's algorithm
+ *
+ * Created by: Philipp Rudo <prudo@redhat.com>
+ *
+ * Copyright (c) 2022 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdlib.h>
+
+#include "detect_cycle.h"
+
+struct detect_cycle {
+ /* First entry of the list */
+ void *head;
+
+ /* Variables required by Brent's algorithm */
+ void *fast_p;
+ void *slow_p;
+ unsigned long length;
+ unsigned long power;
+
+ /* Function to get the next entry in the list */
+ dc_next_t next;
+
+ /* Private data passed to next */
+ void *data;
+};
+
+struct detect_cycle *dc_init(void *head, void *data, dc_next_t next)
+{
+ struct detect_cycle *new;
+
+ new = malloc(sizeof(*new));
+ if (!new)
+ return NULL;
+
+ new->next = next;
+ new->data = data;
+
+ new->head = head;
+ new->slow_p = head;
+ new->fast_p = head;
+ new->length = 0;
+ new->power = 2;
+
+ return new;
+}
+
+int dc_next(struct detect_cycle *dc, void **next)
+{
+
+ if (dc->length == dc->power) {
+ dc->length = 0;
+ dc->power *= 2;
+ dc->slow_p = dc->fast_p;
+ }
+
+ dc->fast_p = dc->next(dc->fast_p, dc->data);
+ dc->length++;
+
+ if (dc->slow_p == dc->fast_p)
+ return 1;
+
+ *next = dc->fast_p;
+ return 0;
+}
+
+void dc_find_start(struct detect_cycle *dc, void **first, unsigned long *len)
+{
+ void *slow_p, *fast_p;
+ unsigned long tmp;
+
+ slow_p = fast_p = dc->head;
+ tmp = dc->length;
+
+ while (tmp) {
+ fast_p = dc->next(fast_p, dc->data);
+ tmp--;
+ }
+
+ while (slow_p != fast_p) {
+ slow_p = dc->next(slow_p, dc->data);
+ fast_p = dc->next(fast_p, dc->data);
+ }
+
+ *first = slow_p;
+ *len = dc->length;
+}
diff --git a/makedumpfile-1.7.0/detect_cycle.h b/makedumpfile-1.7.0/detect_cycle.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ca75c78b59a98274fc5a98666b1be74f7bbfc2c
--- /dev/null
+++ b/makedumpfile-1.7.0/detect_cycle.h
@@ -0,0 +1,40 @@
+/*
+ * detect_cycle.h -- Generic cycle detection using Brent's algorithm
+ *
+ * Created by: Philipp Rudo <prudo@redhat.com>
+ *
+ * Copyright (c) 2022 Red Hat, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+struct detect_cycle;
+
+typedef void *(*dc_next_t)(void *prev, void *data);
+
+/*
+ * Initialize cycle detection.
+ * Returns a pointer to allocated struct detect_cycle. The caller is
+ * responsible to free the memory after use.
+ */
+struct detect_cycle *dc_init(void *head, void *data, dc_next_t next);
+
+/*
+ * Get next entry in the list using dc->next.
+ * Returns 1 when cycle was detected, 0 otherwise.
+ */
+int dc_next(struct detect_cycle *dc, void **next);
+
+/*
+ * Get the start and length of the cycle. Must only be called after cycle was
+ * detected by dc_next.
+ */
+void dc_find_start(struct detect_cycle *dc, void **first, unsigned long *len);

View File

@ -1,216 +0,0 @@
commit defb80a20bf1e4d778596ce2447e19d44f31ae5a
Author: Sven Schnelle <svens@linux.ibm.com>
Date: Thu Dec 16 12:43:52 2021 +0100
s390: add variable command line size
Newer s390 kernels support a command line size longer than 896
bytes. Such kernels contain a new member in the parameter area,
which might be utilized by tools like kexec. Older kernels have
the location initialized to zero, so we check whether there's a
non-zero number present and use that. If there isn't, we fallback
to the legacy command line size of 896 bytes.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/kexec/arch/s390/crashdump-s390.c b/kexec/arch/s390/crashdump-s390.c
index 10f4d607bbcc1aea362de3de687b0e7b2401d879..3bd9efe6dafebab2f364c656ae703c71c4494c35 100644
--- a/kexec/arch/s390/crashdump-s390.c
+++ b/kexec/arch/s390/crashdump-s390.c
@@ -52,7 +52,8 @@ static int create_elf_header(struct kexec_info *info, unsigned long crash_base,
elfcorehdr_size = bufsz;
snprintf(str, sizeof(str), " elfcorehdr=%ld@%ldK\n",
elfcorehdr_size, elfcorehdr / 1024);
- command_line_add(str);
+ if (command_line_add(info, str))
+ return -1;
#endif
return 0;
}
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
index 3c24fdfe3c7ccafddee9fb4a68c0d8874cf6a61e..a52399eafd2abd4a24142f0512251598ea812ca5 100644
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -25,7 +25,6 @@
#include <fcntl.h>
static uint64_t crash_base, crash_end;
-static char command_line[COMMAND_LINESIZE];
static void add_segment_check(struct kexec_info *info, const void *buf,
size_t bufsz, unsigned long base, size_t memsz)
@@ -36,13 +35,18 @@ static void add_segment_check(struct kexec_info *info, const void *buf,
add_segment(info, buf, bufsz, crash_base + base, memsz);
}
-int command_line_add(const char *str)
+int command_line_add(struct kexec_info *info, const char *str)
{
- if (strlen(command_line) + strlen(str) + 1 > COMMAND_LINESIZE) {
- fprintf(stderr, "Command line too long.\n");
+ char *tmp = NULL;
+
+ tmp = concat_cmdline(info->command_line, str);
+ if (!tmp) {
+ fprintf(stderr, "out of memory\n");
return -1;
}
- strcat(command_line, str);
+
+ free(info->command_line);
+ info->command_line = tmp;
return 0;
}
@@ -64,7 +68,7 @@ int image_s390_load_file(int argc, char **argv, struct kexec_info *info)
while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
switch(opt) {
case OPT_APPEND:
- if (command_line_add(optarg))
+ if (command_line_add(info, optarg))
return -1;
break;
case OPT_RAMDISK:
@@ -78,13 +82,16 @@ int image_s390_load_file(int argc, char **argv, struct kexec_info *info)
if (info->initrd_fd == -1) {
fprintf(stderr, "Could not open initrd file %s:%s\n",
ramdisk, strerror(errno));
+ free(info->command_line);
+ info->command_line = NULL;
return -1;
}
}
- info->command_line = command_line;
- info->command_line_len = strlen (command_line) + 1;
-
+ if (info->command_line)
+ info->command_line_len = strlen(info->command_line) + 1;
+ else
+ info->command_line_len = 0;
return 0;
}
@@ -97,7 +104,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
const char *ramdisk;
off_t ramdisk_len;
unsigned int ramdisk_origin;
- int opt;
+ int opt, ret = -1;
if (info->file_mode)
return image_s390_load_file(argc, argv, info);
@@ -120,7 +126,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) {
switch(opt) {
case OPT_APPEND:
- if (command_line_add(optarg))
+ if (command_line_add(info, optarg))
return -1;
break;
case OPT_RAMDISK:
@@ -132,7 +138,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
if (info->kexec_flags & KEXEC_ON_CRASH) {
if (parse_iomem_single("Crash kernel\n", &crash_base,
&crash_end))
- return -1;
+ goto out;
}
/* Add kernel segment */
@@ -151,7 +157,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
rd_buffer = slurp_file_mmap(ramdisk, &ramdisk_len);
if (rd_buffer == NULL) {
fprintf(stderr, "Could not read ramdisk.\n");
- return -1;
+ goto out;
}
ramdisk_origin = MAX(RAMDISK_ORIGIN_ADDR, kernel_size);
ramdisk_origin = _ALIGN_UP(ramdisk_origin, 0x100000);
@@ -160,7 +166,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
}
if (info->kexec_flags & KEXEC_ON_CRASH) {
if (load_crashdump_segments(info, crash_base, crash_end))
- return -1;
+ goto out;
} else {
info->entry = (void *) IMAGE_READ_OFFSET;
}
@@ -183,15 +189,28 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
*tmp = crash_end - crash_base + 1;
}
}
- /*
- * We will write a probably given command line.
- * First, erase the old area, then setup the new parameters:
- */
- if (strlen(command_line) != 0) {
- memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE);
- memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line));
+
+ if (info->command_line) {
+ unsigned long maxsize;
+ char *dest = krnl_buffer + COMMAND_LINE_OFFS;
+
+ maxsize = *(unsigned long *)(krnl_buffer + MAX_COMMAND_LINESIZE_OFFS);
+ if (!maxsize)
+ maxsize = LEGACY_COMMAND_LINESIZE;
+
+ if (strlen(info->command_line) > maxsize-1) {
+ fprintf(stderr, "command line too long, maximum allowed size %ld\n",
+ maxsize-1);
+ goto out;
+ }
+ strncpy(dest, info->command_line, maxsize-1);
+ dest[maxsize-1] = '\0';
}
- return 0;
+ ret = 0;
+out:
+ free(info->command_line);
+ info->command_line = NULL;
+ return ret;
}
int
diff --git a/kexec/arch/s390/kexec-s390.h b/kexec/arch/s390/kexec-s390.h
index ef53b111e16719d15e5364c18435e272f98b9086..6a99518c1c9e411ed853489daf0de6463972ab6f 100644
--- a/kexec/arch/s390/kexec-s390.h
+++ b/kexec/arch/s390/kexec-s390.h
@@ -10,16 +10,17 @@
#ifndef KEXEC_S390_H
#define KEXEC_S390_H
-#define IMAGE_READ_OFFSET 0x10000
+#define IMAGE_READ_OFFSET 0x10000
-#define RAMDISK_ORIGIN_ADDR 0x800000
-#define INITRD_START_OFFS 0x408
-#define INITRD_SIZE_OFFS 0x410
-#define OLDMEM_BASE_OFFS 0x418
-#define OLDMEM_SIZE_OFFS 0x420
-#define COMMAND_LINE_OFFS 0x480
-#define COMMAND_LINESIZE 896
-#define MAX_MEMORY_RANGES 1024
+#define RAMDISK_ORIGIN_ADDR 0x800000
+#define INITRD_START_OFFS 0x408
+#define INITRD_SIZE_OFFS 0x410
+#define OLDMEM_BASE_OFFS 0x418
+#define OLDMEM_SIZE_OFFS 0x420
+#define MAX_COMMAND_LINESIZE_OFFS 0x430
+#define COMMAND_LINE_OFFS 0x480
+#define LEGACY_COMMAND_LINESIZE 896
+#define MAX_MEMORY_RANGES 1024
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
@@ -32,6 +33,6 @@ extern int load_crashdump_segments(struct kexec_info *info,
unsigned long crash_end);
extern int get_memory_ranges_s390(struct memory_range range[], int *ranges,
int with_crashk);
-extern int command_line_add(const char *str);
+extern int command_line_add(struct kexec_info *info, const char *str);
#endif /* KEXEC_S390_H */

View File

@ -1,102 +0,0 @@
commit e1d2e5302b016c6f7942f46ffa27aa31326686c5
Author: Philipp Rudo <prudo@redhat.com>
Date: Mon Mar 14 17:04:30 2022 +0100
[PATCH v2 2/3] use pointer arithmetics for dump_dmesg
When parsing the printk buffer for the old printk mechanism (> v3.5.0+ and
< 5.10.0) a log entry is currently specified by the offset into the
buffer where the entry starts. Change this to use a pointers instead.
This is done in preparation for using the new cycle detection mechanism.
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Reviewed-and-tested-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c
index 7ed9756a8c43ae4a2b6770e86dc81763796c2187..e72dba219eec198ec865045562f39a14b5a092eb 100644
--- a/makedumpfile-1.7.0/makedumpfile.c
+++ b/makedumpfile-1.7.0/makedumpfile.c
@@ -5482,13 +5482,10 @@ dump_log_entry(char *logptr, int fp, const char *file_name)
* get log record by index; idx must point to valid message.
*/
static char *
-log_from_idx(unsigned int idx, char *logbuf)
+log_from_ptr(char *logptr, char *logbuf)
{
- char *logptr;
unsigned int msglen;
- logptr = logbuf + idx;
-
/*
* A length == 0 record is the end of buffer marker.
* Wrap around and return the message at the start of
@@ -5497,19 +5494,16 @@ log_from_idx(unsigned int idx, char *logbuf)
msglen = USHORT(logptr + OFFSET(printk_log.len));
if (!msglen)
- logptr = logbuf;
+ return logbuf;
return logptr;
}
-static long
-log_next(unsigned int idx, char *logbuf)
+static void *
+log_next(void *logptr, void *logbuf)
{
- char *logptr;
unsigned int msglen;
- logptr = logbuf + idx;
-
/*
* A length == 0 record is the end of buffer marker. Wrap around and
* read the message at the start of the buffer as *this* one, and
@@ -5519,10 +5513,10 @@ log_next(unsigned int idx, char *logbuf)
msglen = USHORT(logptr + OFFSET(printk_log.len));
if (!msglen) {
msglen = USHORT(logbuf + OFFSET(printk_log.len));
- return msglen;
+ return logbuf + msglen;
}
- return idx + msglen;
+ return logptr + msglen;
}
int
@@ -5530,11 +5524,12 @@ dump_dmesg()
{
int log_buf_len, length_log, length_oldlog, ret = FALSE;
unsigned long index, log_buf, log_end;
- unsigned int idx, log_first_idx, log_next_idx;
+ unsigned int log_first_idx, log_next_idx;
unsigned long long first_idx_sym;
unsigned long log_end_2_6_24;
unsigned log_end_2_6_25;
char *log_buffer = NULL, *log_ptr = NULL;
+ char *ptr;
/*
* log_end has been changed to "unsigned" since linux-2.6.25.
@@ -5681,13 +5676,13 @@ dump_dmesg()
ERRMSG("Can't open output file.\n");
goto out;
}
- idx = log_first_idx;
- while (idx != log_next_idx) {
- log_ptr = log_from_idx(idx, log_buffer);
+ ptr = log_buffer + log_first_idx;
+ while (ptr != log_buffer + log_next_idx) {
+ log_ptr = log_from_ptr(ptr, log_buffer);
if (!dump_log_entry(log_ptr, info->fd_dumpfile,
info->name_dumpfile))
goto out;
- idx = log_next(idx, log_buffer);
+ ptr = log_next(ptr, log_buffer);
}
if (!close_files_for_creating_dumpfile())
goto out;

View File

@ -1,43 +0,0 @@
commit 91a3d0e00a5c18ee9bdd2c6c03ac64a6471e2559
Author: Sven Schnelle <svens@linux.ibm.com>
Date: Thu Dec 16 12:43:53 2021 +0100
s390: use KEXEC_ALL_OPTIONS
KEXEC_ALL_OPTIONS could be used instead defining the same
array several times. This makes code easier to maintain when
new options are added.
Suggested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
index a52399eafd2abd4a24142f0512251598ea812ca5..209ab77ddccbd60f10989e2d9fc273324aefa76d 100644
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -57,10 +57,7 @@ int image_s390_load_file(int argc, char **argv, struct kexec_info *info)
static const struct option options[] =
{
- KEXEC_OPTIONS
- {"command-line", 1, 0, OPT_APPEND},
- {"append", 1, 0, OPT_APPEND},
- {"initrd", 1, 0, OPT_RAMDISK},
+ KEXEC_ALL_OPTIONS
{0, 0, 0, 0},
};
static const char short_options[] = KEXEC_OPT_STR "";
@@ -111,10 +108,7 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
static const struct option options[] =
{
- KEXEC_OPTIONS
- {"command-line", 1, 0, OPT_APPEND},
- {"append", 1, 0, OPT_APPEND},
- {"initrd", 1, 0, OPT_RAMDISK},
+ KEXEC_ALL_OPTIONS
{0, 0, 0, 0},
};
static const char short_options[] = KEXEC_OPT_STR "";

View File

@ -1,118 +0,0 @@
commit 68d120b30af5e930afafed81e79712af3c1a278c
Author: Philipp Rudo <prudo@redhat.com>
Date: Mon Mar 14 17:04:31 2022 +0100
[PATCH v2 3/3] use cycle detection when parsing the prink log_buf
The old printk mechanism (> v3.5.0 and < v5.10.0) had a fixed size
buffer (log_buf) that contains all messages. The location for the next
message is stored in log_next_idx. In case the log_buf runs full
log_next_idx wraps around and starts overwriting old messages at the
beginning of the buffer. The wraparound is denoted by a message with
msg->len == 0.
Following the behavior described above blindly in makedumpfile is
dangerous as e.g. a memory corruption could overwrite (parts of) the
log_buf. If the corruption adds a message with msg->len == 0 this leads
to an endless loop when dumping the dmesg with makedumpfile appending
the messages up to the corruption over and over again to the output file
until file system is full. Fix this by using cycle detection and aboard
once one is detected.
While at it also verify that the index is within the log_buf and thus
guard against corruptions with msg->len != 0.
Reported-by: Audra Mitchell <aubaker@redhat.com>
Suggested-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Reviewed-and-tested-by: Dave Wysochanski <dwysocha@redhat.com>
diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c
index e72dba219eec198ec865045562f39a14b5a092eb..2b94446b8f2ad513da060e15821544ae32e1a2c6 100644
--- a/makedumpfile-1.7.0/makedumpfile.c
+++ b/makedumpfile-1.7.0/makedumpfile.c
@@ -15,6 +15,7 @@
*/
#include "makedumpfile.h"
#include "print_info.h"
+#include "detect_cycle.h"
#include "dwarf_info.h"
#include "elf_info.h"
#include "erase_info.h"
@@ -5526,10 +5527,11 @@ dump_dmesg()
unsigned long index, log_buf, log_end;
unsigned int log_first_idx, log_next_idx;
unsigned long long first_idx_sym;
+ struct detect_cycle *dc = NULL;
unsigned long log_end_2_6_24;
unsigned log_end_2_6_25;
char *log_buffer = NULL, *log_ptr = NULL;
- char *ptr;
+ char *ptr, *next_ptr;
/*
* log_end has been changed to "unsigned" since linux-2.6.25.
@@ -5677,12 +5679,55 @@ dump_dmesg()
goto out;
}
ptr = log_buffer + log_first_idx;
+ dc = dc_init(ptr, log_buffer, log_next);
while (ptr != log_buffer + log_next_idx) {
log_ptr = log_from_ptr(ptr, log_buffer);
if (!dump_log_entry(log_ptr, info->fd_dumpfile,
info->name_dumpfile))
goto out;
ptr = log_next(ptr, log_buffer);
+ if (dc_next(dc, (void **) &next_ptr)) {
+ unsigned long len;
+ int in_cycle;
+ char *first;
+
+ /* Clear everything we have already written... */
+ ftruncate(info->fd_dumpfile, 0);
+ lseek(info->fd_dumpfile, 0, SEEK_SET);
+
+ /* ...and only write up to the corruption. */
+ dc_find_start(dc, (void **) &first, &len);
+ ptr = log_buffer + log_first_idx;
+ in_cycle = FALSE;
+ while (len) {
+ log_ptr = log_from_ptr(ptr, log_buffer);
+ if (!dump_log_entry(log_ptr,
+ info->fd_dumpfile,
+ info->name_dumpfile))
+ goto out;
+ ptr = log_next(ptr, log_buffer);
+
+ if (log_ptr == first)
+ in_cycle = TRUE;
+
+ if (in_cycle)
+ len--;
+ }
+ ERRMSG("Cycle when parsing dmesg detected.\n");
+ ERRMSG("The printk log_buf is most likely corrupted.\n");
+ ERRMSG("log_buf = 0x%lx, idx = 0x%lx\n", log_buf, ptr - log_buffer);
+ close_files_for_creating_dumpfile();
+ goto out;
+ }
+ if (next_ptr < log_buffer ||
+ next_ptr > log_buffer + log_buf_len - SIZE(printk_log)) {
+ ERRMSG("Index outside log_buf detected.\n");
+ ERRMSG("The printk log_buf is most likely corrupted.\n");
+ ERRMSG("log_buf = 0x%lx, idx = 0x%lx\n", log_buf, ptr - log_buffer);
+ close_files_for_creating_dumpfile();
+ goto out;
+ }
+ ptr = next_ptr;
}
if (!close_files_for_creating_dumpfile())
goto out;
@@ -5692,6 +5737,7 @@ dump_dmesg()
out:
if (log_buffer)
free(log_buffer);
+ free(dc);
return ret;
}

View File

@ -1,76 +0,0 @@
commit 193e51deccc62544f6423eb5e5eefc8a23aad679
Author: Sven Schnelle <svens@linux.ibm.com>
Date: Thu Dec 16 12:43:54 2021 +0100
add slurp_proc_file()
slurp_file() cannot be used to read proc files, as they are returning
a size of zero in stat(). Add a function slurp_proc_file() which is
similar to slurp_file(), but doesn't require the size of the file to
be known.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/kexec/kexec.c b/kexec/kexec.c
index f63b36b771eb95a93f07a7c286c4974a558aec8d..f3adac517161d448552a16fd79488c1df100d356 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1106,6 +1106,57 @@ static void remove_parameter(char *line, const char *param_name)
}
}
+static ssize_t _read(int fd, void *buf, size_t count)
+{
+ ssize_t ret, offset = 0;
+
+ do {
+ ret = read(fd, buf + offset, count - offset);
+ if (ret < 0) {
+ if ((errno == EINTR) || (errno == EAGAIN))
+ continue;
+ return ret;
+ }
+ offset += ret;
+ } while (ret && offset < count);
+
+ return offset;
+}
+
+static char *slurp_proc_file(const char *filename, size_t *len)
+{
+ ssize_t ret, startpos = 0;
+ unsigned int size = 64;
+ char *buf = NULL, *tmp;
+ int fd;
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ return NULL;
+
+ do {
+ size *= 2;
+ tmp = realloc(buf, size);
+ if (!tmp) {
+ free(buf);
+ return NULL;
+ }
+ buf = tmp;
+
+ ret = _read(fd, buf + startpos, size - startpos);
+ if (ret < 0) {
+ free(buf);
+ return NULL;
+ }
+
+ startpos += ret;
+
+ } while(ret);
+
+ *len = startpos;
+ return buf;
+}
+
/*
* Returns the contents of the current command line to be used with
* --reuse-cmdline option. The function gets called from architecture specific

View File

@ -1,150 +0,0 @@
commit 5035c0821f07da3badda645cd0064d4b80e1667d
Author: Philipp Rudo <prudo@redhat.com>
Date: Mon Mar 14 17:04:32 2022 +0100
[PATCH] print error when reading with unsupported compression
Currently makedumpfile only checks if the required compression algorithm
was enabled during build when compressing a dump but not when reading
from one. This can lead to situations where, one version of makedumpfile
creates the dump using a compression algorithm an other version of
makedumpfile doesn't support. When the second version now tries to, e.g.
extract the dmesg from the dump it will fail with an error similar to
# makedumpfile --dump-dmesg vmcore dmesg.txt
__vtop4_x86_64: Can't get a valid pgd.
readmem: Can't convert a virtual address(ffffffff92e18284) to physical address.
readmem: type_addr: 0, addr:ffffffff92e18284, size:390
check_release: Can't get the address of system_utsname.
makedumpfile Failed.
That's because readpage_kdump_compressed{_parallel} does not return
with an error if the page it is trying to read is compressed with an
unsupported compression algorithm. Thus readmem copies random data from
the (uninitialized) cachebuf to its caller and thus causing the error
above.
Fix this by checking if the required compression algorithm is supported
in readpage_kdump_compressed{_parallel} and print a proper error message
if it isn't.
Reported-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Reviewed-and-tested-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c
index 2b94446b8f2ad513da060e15821544ae32e1a2c6..14556db15627617cb394bba85bb7ebec6b35fb34 100644
--- a/makedumpfile-1.7.0/makedumpfile.c
+++ b/makedumpfile-1.7.0/makedumpfile.c
@@ -865,9 +865,13 @@ readpage_kdump_compressed(unsigned long long paddr, void *bufptr)
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+ } else if ((pd.flags & DUMP_DH_COMPRESSED_LZO)) {
#ifdef USELZO
- } else if (info->flag_lzo_support
- && (pd.flags & DUMP_DH_COMPRESSED_LZO)) {
+ if (!info->flag_lzo_support) {
+ ERRMSG("lzo compression unsupported\n");
+ return FALSE;
+ }
+
retlen = info->page_size;
ret = lzo1x_decompress_safe((unsigned char *)buf, pd.size,
(unsigned char *)bufptr, &retlen,
@@ -876,9 +880,13 @@ readpage_kdump_compressed(unsigned long long paddr, void *bufptr)
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("lzo compression unsupported\n");
+ ERRMSG("Try `make USELZO=on` when building.\n");
+ return FALSE;
#endif
-#ifdef USESNAPPY
} else if ((pd.flags & DUMP_DH_COMPRESSED_SNAPPY)) {
+#ifdef USESNAPPY
ret = snappy_uncompressed_length(buf, pd.size, (size_t *)&retlen);
if (ret != SNAPPY_OK) {
@@ -891,14 +899,22 @@ readpage_kdump_compressed(unsigned long long paddr, void *bufptr)
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("snappy compression unsupported\n");
+ ERRMSG("Try `make USESNAPPY=on` when building.\n");
+ return FALSE;
#endif
-#ifdef USEZSTD
} else if ((pd.flags & DUMP_DH_COMPRESSED_ZSTD)) {
+#ifdef USEZSTD
ret = ZSTD_decompress(bufptr, info->page_size, buf, pd.size);
if (ZSTD_isError(ret) || (ret != info->page_size)) {
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("zstd compression unsupported\n");
+ ERRMSG("Try `make USEZSTD=on` when building.\n");
+ return FALSE;
#endif
}
@@ -964,9 +980,13 @@ readpage_kdump_compressed_parallel(int fd_memory, unsigned long long paddr,
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+ } else if ((pd.flags & DUMP_DH_COMPRESSED_LZO)) {
#ifdef USELZO
- } else if (info->flag_lzo_support
- && (pd.flags & DUMP_DH_COMPRESSED_LZO)) {
+ if (!info->flag_lzo_support) {
+ ERRMSG("lzo compression unsupported\n");
+ return FALSE;
+ }
+
retlen = info->page_size;
ret = lzo1x_decompress_safe((unsigned char *)buf, pd.size,
(unsigned char *)bufptr, &retlen,
@@ -975,9 +995,13 @@ readpage_kdump_compressed_parallel(int fd_memory, unsigned long long paddr,
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("lzo compression unsupported\n");
+ ERRMSG("Try `make USELZO=on` when building.\n");
+ return FALSE;
#endif
-#ifdef USESNAPPY
} else if ((pd.flags & DUMP_DH_COMPRESSED_SNAPPY)) {
+#ifdef USESNAPPY
ret = snappy_uncompressed_length(buf, pd.size, (size_t *)&retlen);
if (ret != SNAPPY_OK) {
@@ -990,14 +1014,22 @@ readpage_kdump_compressed_parallel(int fd_memory, unsigned long long paddr,
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("snappy compression unsupported\n");
+ ERRMSG("Try `make USESNAPPY=on` when building.\n");
+ return FALSE;
#endif
-#ifdef USEZSTD
} else if ((pd.flags & DUMP_DH_COMPRESSED_ZSTD)) {
+#ifdef USEZSTD
ret = ZSTD_decompress(bufptr, info->page_size, buf, pd.size);
if (ZSTD_isError(ret) || (ret != info->page_size)) {
ERRMSG("Uncompress failed: %d\n", ret);
return FALSE;
}
+#else
+ ERRMSG("zstd compression unsupported\n");
+ ERRMSG("Try `make USEZSTD=on` when building.\n");
+ return FALSE;
#endif
}

View File

@ -1,52 +0,0 @@
commit d6516ba4c88f217fe14455db92c60cd0e9af18f8
Author: Sven Schnelle <svens@linux.ibm.com>
Date: Thu Dec 16 12:43:55 2021 +0100
use slurp_proc_file() in get_command_line()
This way the size of the command line that get_command_line() can handle
is no longer fixed.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/kexec/kexec.c b/kexec/kexec.c
index f3adac517161d448552a16fd79488c1df100d356..7e4787bc821107b7af66ebdbcfc31f4e7e1d48cd 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1172,25 +1172,19 @@ static char *slurp_proc_file(const char *filename, size_t *len)
*/
char *get_command_line(void)
{
- FILE *fp;
- char *line;
- const int sizeof_line = 2048;
-
- line = malloc(sizeof_line);
- if (line == NULL)
- die("Could not allocate memory to read /proc/cmdline.");
-
- fp = fopen("/proc/cmdline", "r");
- if (!fp)
- die("Could not open /proc/cmdline.");
-
- if (fgets(line, sizeof_line, fp) == NULL)
- die("Can't read /proc/cmdline.");
+ char *p, *line;
+ size_t size;
- fclose(fp);
+ line = slurp_proc_file("/proc/cmdline", &size);
+ if (!line || !size)
+ die("Failed to read /proc/cmdline\n");
/* strip newline */
- line[strlen(line) - 1] = '\0';
+ line[size-1] = '\0';
+
+ p = strpbrk(line, "\r\n");
+ if (p)
+ *p = '\0';
remove_parameter(line, "BOOT_IMAGE");
if (kexec_flags & KEXEC_ON_CRASH)

View File

@ -1,75 +0,0 @@
commit 2e1ec106dc5aac951ba884ebe4cca036e9a2d45f
Author: Sven Schnelle <svens@linux.ibm.com>
Date: Thu Dec 16 12:43:56 2021 +0100
s390: add support for --reuse-cmdline
--reuse-cmdline reads the command line of the currently
running kernel from /proc/cmdline and uses that for the
kernel that should be kexec'd.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/kexec/arch/s390/include/arch/options.h b/kexec/arch/s390/include/arch/options.h
index 76044a301ceb3cca013f70dff330a8ad343d808a..c150244996c79165cf1e83e331f728432b752652 100644
--- a/kexec/arch/s390/include/arch/options.h
+++ b/kexec/arch/s390/include/arch/options.h
@@ -1,9 +1,10 @@
#ifndef KEXEC_ARCH_S390_OPTIONS_H
#define KEXEC_ARCH_S390_OPTIONS_H
-#define OPT_ARCH_MAX (OPT_MAX+0)
-#define OPT_APPEND OPT_MAX+0
-#define OPT_RAMDISK OPT_MAX+1
+#define OPT_ARCH_MAX (OPT_MAX+0)
+#define OPT_APPEND (OPT_MAX+0)
+#define OPT_RAMDISK (OPT_MAX+1)
+#define OPT_REUSE_CMDLINE (OPT_MAX+2)
/* Options relevant to the architecture (excluding loader-specific ones),
* in this case none:
@@ -31,7 +32,8 @@
KEXEC_ARCH_OPTIONS \
{"command-line", 1, 0, OPT_APPEND}, \
{"append", 1, 0, OPT_APPEND}, \
- {"initrd", 1, 0, OPT_RAMDISK},
+ {"initrd", 1, 0, OPT_RAMDISK}, \
+ {"reuse-cmdline", 0, 0, OPT_REUSE_CMDLINE },
#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
index 209ab77ddccbd60f10989e2d9fc273324aefa76d..69aaf96812f741110bf323b4bb8d5dda155f293a 100644
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -71,6 +71,10 @@ int image_s390_load_file(int argc, char **argv, struct kexec_info *info)
case OPT_RAMDISK:
ramdisk = optarg;
break;
+ case OPT_REUSE_CMDLINE:
+ free(info->command_line);
+ info->command_line = get_command_line();
+ break;
}
}
@@ -123,6 +127,10 @@ image_s390_load(int argc, char **argv, const char *kernel_buf,
if (command_line_add(info, optarg))
return -1;
break;
+ case OPT_REUSE_CMDLINE:
+ free(info->command_line);
+ info->command_line = get_command_line();
+ break;
case OPT_RAMDISK:
ramdisk = optarg;
break;
@@ -223,5 +231,6 @@ image_s390_usage(void)
printf("--command-line=STRING Set the kernel command line to STRING.\n"
"--append=STRING Set the kernel command line to STRING.\n"
"--initrd=FILENAME Use the file FILENAME as a ramdisk.\n"
+ "--reuse-cmdline Use kernel command line from running system.\n"
);
}

View File

@ -1,86 +0,0 @@
commit f4c59879b830c7d574a953e6ce970ddaf20910d7
Author: Philipp Rudo <prudo@redhat.com>
Date: Wed Mar 23 16:35:36 2022 +0100
util_lib/elf_info: harden parsing of printk buffer
The old printk mechanism (> v3.5.0 and < v5.10.0) had a fixed size
buffer (log_buf) that contains all messages. The location for the next
message is stored in log_next_idx. In case the log_buf runs full
log_next_idx wraps around and starts overwriting old messages at the
beginning of the buffer. The wraparound is denoted by a message with
msg->len == 0.
Following the behavior described above blindly is dangerous as e.g. a
memory corruption could overwrite (parts of) the log_buf. If the
corruption adds a message with msg->len == 0 this leads to an endless
loop when dumping the dmesg. Fix this by verifying that not wrapped
around before when it encounters a message with msg->len == 0.
While at it also verify that the index is within the log_buf and thus
guard against corruptions with msg->len != 0.
The same bug has been reported and fixed in makedumpfile [1].
[1] http://lists.infradead.org/pipermail/kexec/2022-March/024272.html
Signed-off-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index d252eff5bd582837595a22aa387f53675c402121..ce71c6055c3a6ce8698d35960a8448be1dc8adc1 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -763,8 +763,9 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
{
#define OUT_BUF_SIZE 4096
uint64_t log_buf, log_buf_offset, ts_nsec;
- uint32_t log_first_idx, log_next_idx, current_idx, len = 0, i;
+ uint32_t log_buf_len, log_first_idx, log_next_idx, current_idx, len = 0, i;
char *buf, out_buf[OUT_BUF_SIZE];
+ bool has_wrapped_around = false;
ssize_t ret;
char *msg;
uint16_t text_len;
@@ -811,6 +812,7 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
}
log_buf = read_file_pointer(fd, vaddr_to_offset(log_buf_vaddr));
+ log_buf_len = read_file_s32(fd, vaddr_to_offset(log_buf_len_vaddr));
log_first_idx = read_file_u32(fd, vaddr_to_offset(log_first_idx_vaddr));
log_next_idx = read_file_u32(fd, vaddr_to_offset(log_next_idx_vaddr));
@@ -882,11 +884,31 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
* and read the message at the start of the buffer.
*/
loglen = struct_val_u16(buf, log_offset_len);
- if (!loglen)
+ if (!loglen) {
+ if (has_wrapped_around) {
+ if (len && handler)
+ handler(out_buf, len);
+ fprintf(stderr, "Cycle when parsing dmesg detected.\n");
+ fprintf(stderr, "The prink log_buf is most likely corrupted.\n");
+ fprintf(stderr, "log_buf = 0x%lx, idx = 0x%x\n",
+ log_buf, current_idx);
+ exit(68);
+ }
current_idx = 0;
- else
+ has_wrapped_around = true;
+ } else {
/* Move to next record */
current_idx += loglen;
+ if(current_idx > log_buf_len - log_sz) {
+ if (len && handler)
+ handler(out_buf, len);
+ fprintf(stderr, "Index outside log_buf detected.\n");
+ fprintf(stderr, "The prink log_buf is most likely corrupted.\n");
+ fprintf(stderr, "log_buf = 0x%lx, idx = 0x%x\n",
+ log_buf, current_idx);
+ exit(69);
+ }
+ }
}
free(buf);
if (len && handler)

View File

@ -1,492 +0,0 @@
From 4149df9005f2cdd2ecf70058dfe7d72f48c3a68c Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Wed, 25 Nov 2020 23:26:59 +0106
Subject: [PATCH] printk: add support for lockless ringbuffer
Linux 5.10 moved to a new lockless ringbuffer. The new ringbuffer
is structured completely different to the previous iterations.
Add support for retrieving the ringbuffer using vmcoreinfo. The
new ringbuffer is detected based on the availability of the
"prb" symbol.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
util_lib/elf_info.c | 438 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 437 insertions(+), 1 deletion(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 7803a94..2f23a44 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -27,6 +27,32 @@ static int num_pt_loads;
static char osrelease[4096];
+/* VMCOREINFO symbols for lockless printk ringbuffer */
+static loff_t prb_vaddr;
+static size_t printk_ringbuffer_sz;
+static size_t prb_desc_sz;
+static size_t printk_info_sz;
+static uint64_t printk_ringbuffer_desc_ring_offset;
+static uint64_t printk_ringbuffer_text_data_ring_offset;
+static uint64_t prb_desc_ring_count_bits_offset;
+static uint64_t prb_desc_ring_descs_offset;
+static uint64_t prb_desc_ring_infos_offset;
+static uint64_t prb_data_ring_size_bits_offset;
+static uint64_t prb_data_ring_data_offset;
+static uint64_t prb_desc_ring_head_id_offset;
+static uint64_t prb_desc_ring_tail_id_offset;
+static uint64_t atomic_long_t_counter_offset;
+static uint64_t prb_desc_state_var_offset;
+static uint64_t prb_desc_info_offset;
+static uint64_t prb_desc_text_blk_lpos_offset;
+static uint64_t prb_data_blk_lpos_begin_offset;
+static uint64_t prb_data_blk_lpos_next_offset;
+static uint64_t printk_info_seq_offset;
+static uint64_t printk_info_caller_id_offset;
+static uint64_t printk_info_ts_nsec_offset;
+static uint64_t printk_info_level_offset;
+static uint64_t printk_info_text_len_offset;
+
static loff_t log_buf_vaddr;
static loff_t log_end_vaddr;
static loff_t log_buf_len_vaddr;
@@ -304,6 +330,7 @@ void scan_vmcoreinfo(char *start, size_t size)
size_t len;
loff_t *vaddr;
} symbol[] = {
+ SYMBOL(prb),
SYMBOL(log_buf),
SYMBOL(log_end),
SYMBOL(log_buf_len),
@@ -361,6 +388,119 @@ void scan_vmcoreinfo(char *start, size_t size)
*symbol[i].vaddr = vaddr;
}
+ str = "SIZE(printk_ringbuffer)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_ringbuffer_sz = strtoull(pos + strlen(str),
+ NULL, 10);
+
+ str = "SIZE(prb_desc)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_sz = strtoull(pos + strlen(str), NULL, 10);
+
+ str = "SIZE(printk_info)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_sz = strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_ringbuffer.desc_ring)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_ringbuffer_desc_ring_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_ringbuffer.text_data_ring)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_ringbuffer_text_data_ring_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc_ring.count_bits)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_ring_count_bits_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc_ring.descs)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_ring_descs_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc_ring.infos)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_ring_infos_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_data_ring.size_bits)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_data_ring_size_bits_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_data_ring.data)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_data_ring_data_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc_ring.head_id)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_ring_head_id_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc_ring.tail_id)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_ring_tail_id_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(atomic_long_t.counter)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ atomic_long_t_counter_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc.state_var)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_state_var_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc.info)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_info_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_desc.text_blk_lpos)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_desc_text_blk_lpos_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_data_blk_lpos.begin)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_data_blk_lpos_begin_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(prb_data_blk_lpos.next)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ prb_data_blk_lpos_next_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_info.seq)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_seq_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_info.caller_id)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_caller_id_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_info.ts_nsec)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_ts_nsec_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_info.level)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_level_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
+ str = "OFFSET(printk_info.text_len)=";
+ if (memcmp(str, pos, strlen(str)) == 0)
+ printk_info_text_len_offset =
+ strtoull(pos + strlen(str), NULL, 10);
+
/* Check for "SIZE(printk_log)" or older "SIZE(log)=" */
str = "SIZE(log)=";
if (memcmp(str, pos, strlen(str)) == 0)
@@ -746,9 +886,305 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
handler(out_buf, len);
}
+/* convenience struct for passing many values to helper functions */
+struct prb_map {
+ char *prb;
+
+ char *desc_ring;
+ unsigned long desc_ring_count;
+ char *descs;
+
+ char *infos;
+
+ char *text_data_ring;
+ unsigned long text_data_ring_size;
+ char *text_data;
+};
+
+/*
+ * desc_state and DESC_* definitions taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.h
+ *
+ * DESC_* definitions modified to provide 32-bit and 64-bit variants.
+ */
+
+/* The possible responses of a descriptor state-query. */
+enum desc_state {
+ desc_miss = -1, /* ID mismatch (pseudo state) */
+ desc_reserved = 0x0, /* reserved, in use by writer */
+ desc_committed = 0x1, /* committed by writer, could get reopened */
+ desc_finalized = 0x2, /* committed, no further modification allowed */
+ desc_reusable = 0x3, /* free, not yet used by any writer */
+};
+
+#define DESC_SV_BITS (sizeof(uint64_t) * 8)
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
+
+#define DESC32_SV_BITS (sizeof(uint32_t) * 8)
+#define DESC32_FLAGS_SHIFT (DESC32_SV_BITS - 2)
+#define DESC32_FLAGS_MASK (3UL << DESC32_FLAGS_SHIFT)
+#define DESC32_STATE(sv) (3UL & (sv >> DESC32_FLAGS_SHIFT))
+#define DESC32_ID_MASK (~DESC32_FLAGS_MASK)
+#define DESC32_ID(sv) ((sv) & DESC32_ID_MASK)
+
+/*
+ * get_desc_state() taken from kernel source:
+ *
+ * kernel/printk/printk_ringbuffer.c
+ *
+ * get_desc32_state() added as 32-bit variant.
+ */
+
+/* Query the state of a descriptor. */
+static enum desc_state get_desc_state(unsigned long id,
+ uint64_t state_val)
+{
+ if (id != DESC_ID(state_val))
+ return desc_miss;
+
+ return DESC_STATE(state_val);
+}
+
+static enum desc_state get_desc32_state(unsigned long id,
+ uint64_t state_val)
+{
+ if (id != DESC32_ID(state_val))
+ return desc_miss;
+
+ return DESC32_STATE(state_val);
+}
+
+static bool record_committed(unsigned long id, uint64_t state_var)
+{
+ enum desc_state state;
+
+ if (machine_pointer_bits() == 32)
+ state = get_desc32_state(id, state_var);
+ else
+ state = get_desc_state(id, state_var);
+
+ return (state == desc_committed || state == desc_finalized);
+}
+
+static uint64_t id_inc(uint64_t id)
+{
+ id++;
+
+ if (machine_pointer_bits() == 32)
+ return (id & DESC32_ID_MASK);
+
+ return (id & DESC_ID_MASK);
+}
+
+static uint64_t get_ulong(char *addr)
+{
+ if (machine_pointer_bits() == 32)
+ return struct_val_u32(addr, 0);
+ return struct_val_u64(addr, 0);
+}
+
+static uint64_t sizeof_ulong(void)
+{
+ return (machine_pointer_bits() >> 3);
+}
+
+static void dump_record(struct prb_map *m, unsigned long id,
+ void (*handler)(char*, unsigned int))
+{
+#define OUT_BUF_SIZE 4096
+ char out_buf[OUT_BUF_SIZE];
+ imaxdiv_t imaxdiv_usec;
+ imaxdiv_t imaxdiv_sec;
+ uint32_t offset = 0;
+ unsigned short len;
+ uint64_t state_var;
+ uint64_t ts_nsec;
+ uint64_t begin;
+ uint64_t next;
+ char *info;
+ char *text;
+ char *desc;
+ int i;
+
+ desc = m->descs + ((id % m->desc_ring_count) * prb_desc_sz);
+ info = m->infos + ((id % m->desc_ring_count) * printk_info_sz);
+
+ /* skip non-committed record */
+ state_var = get_ulong(desc + prb_desc_state_var_offset +
+ atomic_long_t_counter_offset);
+ if (!record_committed(id, state_var))
+ return;
+
+ begin = get_ulong(desc + prb_desc_text_blk_lpos_offset +
+ prb_data_blk_lpos_begin_offset) %
+ m->text_data_ring_size;
+ next = get_ulong(desc + prb_desc_text_blk_lpos_offset +
+ prb_data_blk_lpos_next_offset) %
+ m->text_data_ring_size;
+
+ ts_nsec = struct_val_u64(info, printk_info_ts_nsec_offset);
+ imaxdiv_sec = imaxdiv(ts_nsec, 1000000000);
+ imaxdiv_usec = imaxdiv(imaxdiv_sec.rem, 1000);
+
+ offset += sprintf(out_buf + offset, "[%5llu.%06llu] ",
+ (long long unsigned int)imaxdiv_sec.quot,
+ (long long unsigned int)imaxdiv_usec.quot);
+
+ /* skip data-less text blocks */
+ if (begin == next)
+ goto out;
+
+ len = struct_val_u16(info, printk_info_text_len_offset);
+
+ /* handle wrapping data block */
+ if (begin > next)
+ begin = 0;
+
+ /* skip over descriptor ID */
+ begin += sizeof_ulong();
+
+ /* handle truncated messages */
+ if (next - begin < len)
+ len = next - begin;
+
+ text = m->text_data + begin;
+
+ /* escape non-printable characters */
+ for (i = 0; i < len; i++) {
+ unsigned char c = text[i];
+
+ if (!isprint(c) && !isspace(c))
+ offset += sprintf(out_buf + offset, "\\x%02x", c);
+ else
+ out_buf[offset++] = c;
+
+ if (offset >= OUT_BUF_SIZE - 64) {
+ if (handler)
+ handler(out_buf, offset);
+ offset = 0;
+ }
+ }
+out:
+ out_buf[offset++] = '\n';
+
+ if (offset && handler)
+ handler(out_buf, offset);
+}
+
+/*
+ * Handle the lockless printk_ringbuffer.
+ */
+static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
+{
+ struct prb_map m;
+ uint64_t head_id;
+ uint64_t tail_id;
+ uint64_t kaddr;
+ uint64_t id;
+ int ret;
+
+ /* setup printk_ringbuffer */
+ kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr));
+ m.prb = calloc(1, printk_ringbuffer_sz);
+ if (!m.prb) {
+ fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n",
+ printk_ringbuffer_sz, strerror(errno));
+ exit(64);
+ }
+ ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr));
+ if (ret != printk_ringbuffer_sz) {
+ fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n",
+ printk_ringbuffer_sz, strerror(errno));
+ exit(65);
+ }
+
+ /* setup descriptor ring */
+ m.desc_ring = m.prb + printk_ringbuffer_desc_ring_offset;
+ m.desc_ring_count = 1 << struct_val_u32(m.desc_ring,
+ prb_desc_ring_count_bits_offset);
+ kaddr = get_ulong(m.desc_ring + prb_desc_ring_descs_offset);
+ m.descs = calloc(1, prb_desc_sz * m.desc_ring_count);
+ if (!m.descs) {
+ fprintf(stderr, "Failed to malloc %lu bytes for descs: %s\n",
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
+ exit(64);
+ }
+ ret = pread(fd, m.descs, prb_desc_sz * m.desc_ring_count,
+ vaddr_to_offset(kaddr));
+ if (ret != prb_desc_sz * m.desc_ring_count) {
+ fprintf(stderr,
+ "Failed to read descs of size %lu bytes: %s\n",
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
+ exit(65);
+ }
+
+ /* setup info ring */
+ kaddr = get_ulong(m.prb + prb_desc_ring_infos_offset);
+ m.infos = calloc(1, printk_info_sz * m.desc_ring_count);
+ if (!m.infos) {
+ fprintf(stderr, "Failed to malloc %lu bytes for infos: %s\n",
+ printk_info_sz * m.desc_ring_count, strerror(errno));
+ exit(64);
+ }
+ ret = pread(fd, m.infos, printk_info_sz * m.desc_ring_count,
+ vaddr_to_offset(kaddr));
+ if (ret != printk_info_sz * m.desc_ring_count) {
+ fprintf(stderr,
+ "Failed to read infos of size %lu bytes: %s\n",
+ printk_info_sz * m.desc_ring_count, strerror(errno));
+ exit(65);
+ }
+
+ /* setup text data ring */
+ m.text_data_ring = m.prb + printk_ringbuffer_text_data_ring_offset;
+ m.text_data_ring_size = 1 << struct_val_u32(m.text_data_ring,
+ prb_data_ring_size_bits_offset);
+ kaddr = get_ulong(m.text_data_ring + prb_data_ring_data_offset);
+ m.text_data = calloc(1, m.text_data_ring_size);
+ if (!m.text_data) {
+ fprintf(stderr,
+ "Failed to malloc %lu bytes for text_data: %s\n",
+ m.text_data_ring_size, strerror(errno));
+ exit(64);
+ }
+ ret = pread(fd, m.text_data, m.text_data_ring_size,
+ vaddr_to_offset(kaddr));
+ if (ret != m.text_data_ring_size) {
+ fprintf(stderr,
+ "Failed to read text_data of size %lu bytes: %s\n",
+ m.text_data_ring_size, strerror(errno));
+ exit(65);
+ }
+
+ /* ready to go */
+
+ tail_id = get_ulong(m.desc_ring + prb_desc_ring_tail_id_offset +
+ atomic_long_t_counter_offset);
+ head_id = get_ulong(m.desc_ring + prb_desc_ring_head_id_offset +
+ atomic_long_t_counter_offset);
+
+ for (id = tail_id; id != head_id; id = id_inc(id))
+ dump_record(&m, id, handler);
+
+ /* dump head record */
+ dump_record(&m, id, handler);
+
+ free(m.text_data);
+ free(m.infos);
+ free(m.descs);
+ free(m.prb);
+}
+
void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
{
- if (log_first_idx_vaddr)
+ if (prb_vaddr)
+ dump_dmesg_lockless(fd, handler);
+ else if (log_first_idx_vaddr)
dump_dmesg_structured(fd, handler);
else
dump_dmesg_legacy(fd, handler);
--
2.31.1

View File

@ -1,65 +0,0 @@
From 07b272a07164b902acd7d12794f7be033ebf4525 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Wed, 17 Mar 2021 13:14:49 +0100
Subject: [PATCH] printk: Use ULL suffix for 64-bit constants
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When compiling for 32-bit:
util_lib/elf_info.c: In function get_desc_state:
util_lib/elf_info.c:923:31: warning: left shift count >= width of type [-Wshift-count-overflow]
923 | #define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
| ^~
util_lib/elf_info.c:925:25: note: in expansion of macro DESC_FLAGS_MASK
925 | #define DESC_ID_MASK (~DESC_FLAGS_MASK)
| ^~~~~~~~~~~~~~~
util_lib/elf_info.c:926:30: note: in expansion of macro DESC_ID_MASK
926 | #define DESC_ID(sv) ((sv) & DESC_ID_MASK)
| ^~~~~~~~~~~~
util_lib/elf_info.c:947:12: note: in expansion of macro DESC_ID
947 | if (id != DESC_ID(state_val))
| ^~~~~~~
util_lib/elf_info.c: In function id_inc:
util_lib/elf_info.c:923:31: warning: left shift count >= width of type [-Wshift-count-overflow]
923 | #define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
| ^~
util_lib/elf_info.c:925:25: note: in expansion of macro DESC_FLAGS_MASK
925 | #define DESC_ID_MASK (~DESC_FLAGS_MASK)
| ^~~~~~~~~~~~~~~
util_lib/elf_info.c:981:15: note: in expansion of macro DESC_ID_MASK
981 | return (id & DESC_ID_MASK);
| ^~~~~~~~~~~~
Indeed, "unsigned long" constants are 32-bit on 32-bit platforms, and
64-bit on 64-bit platforms.
Fix this by using a "ULL" suffix instead.
Fixes: 4149df9005f2cdd2 ("printk: add support for lockless ringbuffer")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
util_lib/elf_info.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 2f23a44..7c0a2c3 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -920,8 +920,8 @@ enum desc_state {
#define DESC_SV_BITS (sizeof(uint64_t) * 8)
#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
-#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
-#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
+#define DESC_FLAGS_MASK (3ULL << DESC_FLAGS_SHIFT)
+#define DESC_STATE(sv) (3ULL & (sv >> DESC_FLAGS_SHIFT))
#define DESC_ID_MASK (~DESC_FLAGS_MASK)
#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
--
2.31.1

View File

@ -1,68 +0,0 @@
From 82f7de2724c42a6aecc0cff93881b3dfd09363ce Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Wed, 17 Mar 2021 13:14:50 +0100
Subject: [PATCH] printk: Use %zu to format size_t
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When compiling for 32-bit:
util_lib/elf_info.c: In function dump_dmesg_lockless:
util_lib/elf_info.c:1095:39: warning: format %lu expects argument of type long unsigned int, but argument 3 has type size_t {aka unsigned int} [-Wformat=]
1095 | fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n",
| ~~^
| |
| long unsigned int
| %u
1096 | printk_ringbuffer_sz, strerror(errno));
| ~~~~~~~~~~~~~~~~~~~~
| |
| size_t {aka unsigned int}
util_lib/elf_info.c:1101:49: warning: format %lu expects argument of type long unsigned int, but argument 3 has type size_t {aka unsigned int} [-Wformat=]
1101 | fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n",
| ~~^
| |
| long unsigned int
| %u
1102 | printk_ringbuffer_sz, strerror(errno));
| ~~~~~~~~~~~~~~~~~~~~
| |
| size_t {aka unsigned int}
Indeed, "size_t" is "unsigned int" on 32-bit platforms, and "unsigned
long" on 64-bit platforms.
Fix this by formatting using "%zu".
Fixes: 4149df9005f2cdd2 ("printk: add support for lockless ringbuffer")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
util_lib/elf_info.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 7c0a2c3..676926c 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -1092,13 +1092,13 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr));
m.prb = calloc(1, printk_ringbuffer_sz);
if (!m.prb) {
- fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n",
+ fprintf(stderr, "Failed to malloc %zu bytes for prb: %s\n",
printk_ringbuffer_sz, strerror(errno));
exit(64);
}
ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr));
if (ret != printk_ringbuffer_sz) {
- fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n",
+ fprintf(stderr, "Failed to read prb of size %zu bytes: %s\n",
printk_ringbuffer_sz, strerror(errno));
exit(65);
}
--
2.31.1

View File

@ -1,181 +0,0 @@
From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 23 Aug 2019 20:05:38 +0800
Subject: [PATCH 3/5] Cleanup: move it back from util_lib/elf_info.c
Some code related to vmcore-dmesg.c is put into the util_lib, which
is not very reasonable, so lets move it back and tidy up those code.
In addition, that will also help to limit the size of vmcore-dmesg.txt
in vmcore-dmesg.c instead of elf_info.c.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
util_lib/elf_info.c | 48 +++++++++----------------------------
util_lib/include/elf_info.h | 2 +-
vmcore-dmesg/vmcore-dmesg.c | 30 ++++++++++++++++++++++-
3 files changed, 41 insertions(+), 39 deletions(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 5d0efaafab53..2bce5cb1713c 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -531,19 +531,7 @@ static int32_t read_file_s32(int fd, uint64_t addr)
return read_file_u32(fd, addr);
}
-static void write_to_stdout(char *buf, unsigned int nr)
-{
- ssize_t ret;
-
- ret = write(STDOUT_FILENO, buf, nr);
- if (ret != nr) {
- fprintf(stderr, "Failed to write out the dmesg log buffer!:"
- " %s\n", strerror(errno));
- exit(54);
- }
-}
-
-static void dump_dmesg_legacy(int fd)
+static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int))
{
uint64_t log_buf, log_buf_offset;
unsigned log_end, logged_chars, log_end_wrapped;
@@ -604,7 +592,8 @@ static void dump_dmesg_legacy(int fd)
*/
logged_chars = log_end < log_buf_len ? log_end : log_buf_len;
- write_to_stdout(buf + (log_buf_len - logged_chars), logged_chars);
+ if (handler)
+ handler(buf + (log_buf_len - logged_chars), logged_chars);
}
static inline uint16_t struct_val_u16(char *ptr, unsigned int offset)
@@ -623,7 +612,7 @@ static inline uint64_t struct_val_u64(char *ptr, unsigned int offset)
}
/* Read headers of log records and dump accordingly */
-static void dump_dmesg_structured(int fd)
+static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
{
#define OUT_BUF_SIZE 4096
uint64_t log_buf, log_buf_offset, ts_nsec;
@@ -733,7 +722,8 @@ static void dump_dmesg_structured(int fd)
out_buf[len++] = c;
if (len >= OUT_BUF_SIZE - 64) {
- write_to_stdout(out_buf, len);
+ if (handler)
+ handler(out_buf, len);
len = 0;
}
}
@@ -752,16 +742,16 @@ static void dump_dmesg_structured(int fd)
current_idx += loglen;
}
free(buf);
- if (len)
- write_to_stdout(out_buf, len);
+ if (len && handler)
+ handler(out_buf, len);
}
-static void dump_dmesg(int fd)
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
{
if (log_first_idx_vaddr)
- dump_dmesg_structured(fd);
+ dump_dmesg_structured(fd, handler);
else
- dump_dmesg_legacy(fd);
+ dump_dmesg_legacy(fd, handler);
}
int read_elf(int fd)
@@ -808,22 +798,6 @@ int read_elf(int fd)
return 0;
}
-int read_elf_vmcore(int fd)
-{
- int ret;
-
- ret = read_elf(fd);
- if (ret > 0) {
- fprintf(stderr, "Unable to read ELF information"
- " from vmcore\n");
- return ret;
- }
-
- dump_dmesg(fd);
-
- return 0;
-}
-
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
{
int ret;
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
index c328a1b0ecf2..4bc9279ba603 100644
--- a/util_lib/include/elf_info.h
+++ b/util_lib/include/elf_info.h
@@ -30,6 +30,6 @@ int get_pt_load(int idx,
unsigned long long *virt_end);
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
int read_elf(int fd);
-int read_elf_vmcore(int fd);
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
#endif /* ELF_INFO_H */
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
index bebc348a657e..fe7df8ec372c 100644
--- a/vmcore-dmesg/vmcore-dmesg.c
+++ b/vmcore-dmesg/vmcore-dmesg.c
@@ -5,6 +5,34 @@ typedef Elf32_Nhdr Elf_Nhdr;
extern const char *fname;
+static void write_to_stdout(char *buf, unsigned int nr)
+{
+ ssize_t ret;
+
+ ret = write(STDOUT_FILENO, buf, nr);
+ if (ret != nr) {
+ fprintf(stderr, "Failed to write out the dmesg log buffer!:"
+ " %s\n", strerror(errno));
+ exit(54);
+ }
+}
+
+static int read_vmcore_dmesg(int fd, void (*handler)(char*, unsigned int))
+{
+ int ret;
+
+ ret = read_elf(fd);
+ if (ret > 0) {
+ fprintf(stderr, "Unable to read ELF information"
+ " from vmcore\n");
+ return ret;
+ }
+
+ dump_dmesg(fd, handler);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
ssize_t ret;
@@ -23,7 +51,7 @@ int main(int argc, char **argv)
return 2;
}
- ret = read_elf_vmcore(fd);
+ ret = read_vmcore_dmesg(fd, write_to_stdout);
close(fd);
--
2.17.1

View File

@ -1,84 +0,0 @@
From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 23 Aug 2019 20:05:36 +0800
Subject: [PATCH 1/5] Cleanup: remove the read_elf_kcore()
Here, no need to wrap the read_elf() again, lets invoke it directly.
So remove the read_elf_kcore() and clean up redundant code.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.c | 2 +-
util_lib/elf_info.c | 15 ++-------------
util_lib/include/elf_info.h | 2 +-
3 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index eb3a3a37307c..6ad3b0a134b3 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -889,7 +889,7 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
return EFAILED;
}
- read_elf_kcore(fd);
+ read_elf(fd);
for (i = 0; get_pt_load(i,
&phys_start, NULL, &virt_start, NULL);
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index 90a3b21662e7..d9397ecd8626 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -764,7 +764,7 @@ static void dump_dmesg(int fd)
dump_dmesg_legacy(fd);
}
-static int read_elf(int fd)
+int read_elf(int fd)
{
int ret;
@@ -824,24 +824,13 @@ int read_elf_vmcore(int fd)
return 0;
}
-int read_elf_kcore(int fd)
-{
- int ret;
-
- ret = read_elf(fd);
- if (ret != 0)
- return ret;
-
- return 0;
-}
-
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
{
int ret;
*phys_off = UINT64_MAX;
- ret = read_elf_kcore(fd);
+ ret = read_elf(fd);
if (!ret) {
/* If we have a valid 'PHYS_OFFSET' by now,
* return it to the caller now.
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
index 1a4debd2d4ba..c328a1b0ecf2 100644
--- a/util_lib/include/elf_info.h
+++ b/util_lib/include/elf_info.h
@@ -29,7 +29,7 @@ int get_pt_load(int idx,
unsigned long long *virt_start,
unsigned long long *virt_end);
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
-int read_elf_kcore(int fd);
+int read_elf(int fd);
int read_elf_vmcore(int fd);
#endif /* ELF_INFO_H */
--
2.17.1

View File

@ -1,47 +0,0 @@
From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 23 Aug 2019 20:05:37 +0800
Subject: [PATCH 2/5] Fix an error definition about the variable 'fname'
The variable 'fname' is mistakenly defined two twice, the first definition
is in the vmcore-dmesg.c, and the second definition is in the elf_info.c.
That is confused and incorrect although it's a static type, because the
value of variable 'fname' is not assigned(set) in elf_info.c. Anyway, its
value will be always 'null' when printing an error information.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
util_lib/elf_info.c | 2 +-
vmcore-dmesg/vmcore-dmesg.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
index d9397ecd8626..5d0efaafab53 100644
--- a/util_lib/elf_info.c
+++ b/util_lib/elf_info.c
@@ -20,7 +20,7 @@
/* The 32bit and 64bit note headers make it clear we don't care */
typedef Elf32_Nhdr Elf_Nhdr;
-static const char *fname;
+const char *fname;
static Elf64_Ehdr ehdr;
static Elf64_Phdr *phdr;
static int num_pt_loads;
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
index 7a386b380291..bebc348a657e 100644
--- a/vmcore-dmesg/vmcore-dmesg.c
+++ b/vmcore-dmesg/vmcore-dmesg.c
@@ -3,7 +3,7 @@
/* The 32bit and 64bit note headers make it clear we don't care */
typedef Elf32_Nhdr Elf_Nhdr;
-static const char *fname;
+extern const char *fname;
int main(int argc, char **argv)
{
--
2.17.1

View File

@ -1,55 +0,0 @@
From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 23 Aug 2019 20:05:39 +0800
Subject: [PATCH 4/5] Limit the size of vmcore-dmesg.txt to 2G
With some corrupted vmcore files, the vmcore-dmesg.txt file may grow
forever till the kdump disk becomes full, and also probably causes
the disk error messages as follow:
...
sd 0:0:0:0: [sda] tag#6 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
sd 0:0:0:0: [sda] tag#6 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
blk_update_request: I/O error, dev sda, sector 134630552
sd 0:0:0:0: [sda] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
sd 0:0:0:0: [sda] tag#7 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
blk_update_request: I/O error, dev sda, sector 134630552
...
If vmcore-dmesg.txt occupies the whole disk, the vmcore can not be
saved, this is also a problem.
Lets limit the size of vmcore-dmesg.txt to avoid such problems.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
vmcore-dmesg/vmcore-dmesg.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
index fe7df8ec372c..81c2a58c9d86 100644
--- a/vmcore-dmesg/vmcore-dmesg.c
+++ b/vmcore-dmesg/vmcore-dmesg.c
@@ -5,9 +5,19 @@ typedef Elf32_Nhdr Elf_Nhdr;
extern const char *fname;
+/* stole this macro from kernel printk.c */
+#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
+
static void write_to_stdout(char *buf, unsigned int nr)
{
ssize_t ret;
+ static uint32_t n_bytes = 0;
+
+ n_bytes += nr;
+ if (n_bytes > LOG_BUF_LEN_MAX) {
+ fprintf(stderr, "The vmcore-dmesg.txt over 2G in size is not supported.\n");
+ exit(53);
+ }
ret = write(STDOUT_FILENO, buf, nr);
if (ret != nr) {
--
2.17.1

View File

@ -1,99 +0,0 @@
From cc087b11462af9f971a2c090d07e8d780a867b50 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Wed, 29 Jan 2020 13:38:19 +0800
Subject: [PATCH] kexec-tools: Remove duplicated variable declarations
When building kexec-tools for Fedora 32, following error is observed:
/usr/bin/ld: kexec/arch/x86_64/kexec-bzImage64.o:(.bss+0x0): multiple definition of `bzImage_support_efi_boot';
kexec/arch/i386/kexec-bzImage.o:(.bss+0x0): first defined here
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm/../../fs2dt.h:33: multiple definition of `my_debug';
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/kexec/fs2dt.h:33: first defined here
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:68: multiple definition of `arm64_mem';
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:68: first defined here
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:54: multiple definition of `initrd_size';
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:54: first defined here
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:53: multiple definition of `initrd_base';
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:53: first defined here
And apparently, these variables are wrongly declared multiple times. So
remove duplicated declaration.
Signed-off-by: Kairui Song <kasong@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.h | 6 +++---
kexec/arch/ppc64/kexec-elf-ppc64.c | 2 --
kexec/arch/x86_64/kexec-bzImage64.c | 1 -
kexec/fs2dt.h | 2 +-
4 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
index 628de79..ed447ac 100644
--- a/kexec/arch/arm64/kexec-arm64.h
+++ b/kexec/arch/arm64/kexec-arm64.h
@@ -50,8 +50,8 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
void zImage_arm64_usage(void);
-off_t initrd_base;
-off_t initrd_size;
+extern off_t initrd_base;
+extern off_t initrd_size;
/**
* struct arm64_mem - Memory layout info.
@@ -65,7 +65,7 @@ struct arm64_mem {
};
#define arm64_mem_ngv UINT64_MAX
-struct arm64_mem arm64_mem;
+extern struct arm64_mem arm64_mem;
uint64_t get_phys_offset(void);
uint64_t get_vp_offset(void);
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
index 3510b70..695b8b0 100644
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
@@ -44,8 +44,6 @@
uint64_t initrd_base, initrd_size;
unsigned char reuse_initrd = 0;
const char *ramdisk;
-/* Used for enabling printing message from purgatory code */
-int my_debug = 0;
int elf_ppc64_probe(const char *buf, off_t len)
{
diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c
index 8edb3e4..ba8dc48 100644
--- a/kexec/arch/x86_64/kexec-bzImage64.c
+++ b/kexec/arch/x86_64/kexec-bzImage64.c
@@ -42,7 +42,6 @@
#include <arch/options.h>
static const int probe_debug = 0;
-int bzImage_support_efi_boot;
int bzImage64_probe(const char *buf, off_t len)
{
diff --git a/kexec/fs2dt.h b/kexec/fs2dt.h
index 7633273..fe24931 100644
--- a/kexec/fs2dt.h
+++ b/kexec/fs2dt.h
@@ -30,7 +30,7 @@ extern struct bootblock bb[1];
/* Used for enabling printing message from purgatory code
* Only has implemented for PPC64 */
-int my_debug;
+extern int my_debug;
extern int dt_no_old_root;
void reserve(unsigned long long where, unsigned long long length);
--
2.7.5

View File

@ -1,82 +0,0 @@
From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Wed, 18 Dec 2019 11:42:32 -0500
Subject: [PATCH 3/3] arm64: kdump: deal with a lot of resource entries in
/proc/iomem
As described in the commit ("arm64: kexec: allocate memory space avoiding
reserved regions"), /proc/iomem now has a lot of "reserved" entries, and
it's not just enough to have a fixed size of memory range array.
With this patch, kdump is allowed to handle arbitrary number of memory
ranges, using mem_regions_alloc_and_xxx() functions.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/crashdump-arm64.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 4fd7aa8fd43c..38d1a0f3000d 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -23,13 +23,8 @@
#include "kexec-elf.h"
#include "mem_regions.h"
-/* memory ranges on crashed kernel */
-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES];
-static struct memory_ranges system_memory_rgns = {
- .size = 0,
- .max_size = CRASH_MAX_MEMORY_RANGES,
- .ranges = system_memory_ranges,
-};
+/* memory ranges of crashed kernel */
+static struct memory_ranges system_memory_rgns;
/* memory range reserved for crashkernel */
struct memory_range crash_reserved_mem;
@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void)
*
* This function is called once for each memory region found in /proc/iomem.
* It locates system RAM and crashkernel reserved memory and places these to
- * variables, respectively, system_memory_ranges and crash_reserved_mem.
+ * variables, respectively, system_memory_rgns and usablemem_rgns.
*/
static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
unsigned long long length)
{
if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
- return mem_regions_add(&usablemem_rgns,
- base, length, RANGE_RAM);
+ return mem_regions_alloc_and_add(&usablemem_rgns,
+ base, length, RANGE_RAM);
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
- return mem_regions_add(&system_memory_rgns,
- base, length, RANGE_RAM);
+ return mem_regions_alloc_and_add(&system_memory_rgns,
+ base, length, RANGE_RAM);
else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
elf_info.kern_paddr_start = base;
else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void)
dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
- fprintf(stderr,
- "Error: Number of crash memory ranges excedeed the max limit\n");
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
+ &crash_reserved_mem)) {
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
return -ENOMEM;
}
--
2.7.4

View File

@ -1,248 +0,0 @@
From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Wed, 18 Dec 2019 11:42:31 -0500
Subject: [PATCH 2/3] arm64: kexec: allocate memory space avoiding reserved
regions
On UEFI/ACPI-only system, some memory regions, including but not limited
to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
Otherwise, they can be corrupted and result in early failure in booting
a new kernel.
In recent kernels, /proc/iomem now has an extended file format like:
40000000-5871ffff : System RAM
41800000-426affff : Kernel code
426b0000-42aaffff : reserved
42ab0000-42c64fff : Kernel data
54400000-583fffff : Crash kernel
58590000-585effff : reserved
58700000-5871ffff : reserved
58720000-58b5ffff : reserved
58b60000-5be3ffff : System RAM
58b61000-58b61fff : reserved
where the "reserved" entries at the top level or under System RAM (and
its descendant resources) are ones of such kind and should not be regarded
as usable memory ranges where several free spaces for loading kexec data
will be allocated.
With this patch, get_memory_ranges() will handle this format of file
correctly. Note that, for safety, unknown regions, in addition to
"reserved" ones, will also be excluded.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/arm64/kexec-arm64.c | 153 +++++++++++++++++++++++++----------------
1 file changed, 94 insertions(+), 59 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 6ad3b0a134b3..45ebc54a9b6f 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -10,7 +10,9 @@
#include <inttypes.h>
#include <libfdt.h>
#include <limits.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <linux/elf-em.h>
#include <elf.h>
@@ -29,6 +31,7 @@
#include "fs2dt.h"
#include "iomem.h"
#include "kexec-syscall.h"
+#include "mem_regions.h"
#include "arch/options.h"
#define ROOT_NODE_ADDR_CELLS_DEFAULT 1
@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
return 0;
}
+static bool to_be_excluded(char *str)
+{
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
+ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
+ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
+ return false;
+ else
+ return true;
+}
+
/**
- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
+ * get_memory_ranges - Try to get the memory ranges from
+ * /proc/iomem.
*/
-
-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
- unsigned long long base, unsigned long long length)
+int get_memory_ranges(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
{
- int ret;
unsigned long phys_offset = UINT64_MAX;
- struct memory_range *r;
-
- if (nr >= KEXEC_SEGMENT_MAX)
- return -1;
+ FILE *fp;
+ const char *iomem = proc_iomem();
+ char line[MAX_LINE], *str;
+ unsigned long long start, end;
+ int n, consumed;
+ struct memory_ranges memranges;
+ struct memory_range *last, excl_range;
+ int ret;
if (!try_read_phys_offset_from_kcore) {
/* Since kernel version 4.19, 'kcore' contains
@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
try_read_phys_offset_from_kcore = true;
}
- r = (struct memory_range *)data + nr;
+ fp = fopen(iomem, "r");
+ if (!fp)
+ die("Cannot open %s\n", iomem);
+
+ memranges.ranges = NULL;
+ memranges.size = memranges.max_size = 0;
+
+ while (fgets(line, sizeof(line), fp) != 0) {
+ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
+ if (n != 2)
+ continue;
+ str = line + consumed;
+
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
+ ret = mem_regions_alloc_and_add(&memranges,
+ start, end - start + 1, RANGE_RAM);
+ if (ret) {
+ fprintf(stderr,
+ "Cannot allocate memory for ranges\n");
+ fclose(fp);
+ return -ENOMEM;
+ }
- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
- r->type = RANGE_RAM;
- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
- r->type = RANGE_RESERVED;
- else
- return 1;
+ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
+ memranges.size - 1,
+ memranges.ranges[memranges.size - 1].start,
+ memranges.ranges[memranges.size - 1].end);
+ } else if (to_be_excluded(str)) {
+ if (!memranges.size)
+ continue;
+
+ /*
+ * Note: mem_regions_exclude() doesn't guarantee
+ * that the ranges are sorted out, but as long as
+ * we cope with /proc/iomem, we only operate on
+ * the last entry and so it is safe.
+ */
- r->start = base;
- r->end = base + length - 1;
+ /* The last System RAM range */
+ last = &memranges.ranges[memranges.size - 1];
+
+ if (last->end < start)
+ /* New resource outside of System RAM */
+ continue;
+ if (end < last->start)
+ /* Already excluded by parent resource */
+ continue;
+
+ excl_range.start = start;
+ excl_range.end = end;
+ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
+ if (ret) {
+ fprintf(stderr,
+ "Cannot allocate memory for ranges (exclude)\n");
+ fclose(fp);
+ return -ENOMEM;
+ }
+ dbgprintf("%s:- %016llx - %016llx\n",
+ __func__, start, end);
+ }
+ }
+
+ fclose(fp);
+
+ *range = memranges.ranges;
+ *ranges = memranges.size;
/* As a fallback option, we can try determining the PHYS_OFFSET
* value from the '/proc/iomem' entries as well.
@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
* between the user-space and kernel space 'PHYS_OFFSET'
* value.
*/
- set_phys_offset(r->start, "iomem");
-
- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
- r->end, str);
-
- return 0;
-}
-
-/**
- * get_memory_ranges_iomem - Try to get the memory ranges from
- * /proc/iomem.
- */
+ if (memranges.size)
+ set_phys_offset(memranges.ranges[0].start, "iomem");
-static int get_memory_ranges_iomem(struct memory_range *array,
- unsigned int *count)
-{
- *count = kexec_iomem_for_each_line(NULL,
- get_memory_ranges_iomem_cb, array);
-
- if (!*count) {
- dbgprintf("%s: failed: No RAM found.\n", __func__);
- return EFAILED;
- }
+ dbgprint_mem_range("System RAM ranges;",
+ memranges.ranges, memranges.size);
return 0;
}
-/**
- * get_memory_ranges - Try to get the memory ranges some how.
- */
-
-int get_memory_ranges(struct memory_range **range, int *ranges,
- unsigned long kexec_flags)
-{
- static struct memory_range array[KEXEC_SEGMENT_MAX];
- unsigned int count;
- int result;
-
- result = get_memory_ranges_iomem(array, &count);
-
- *range = result ? NULL : array;
- *ranges = result ? 0 : count;
-
- return result;
-}
-
int arch_compat_trampoline(struct kexec_info *info)
{
return 0;
--
2.7.4

View File

@ -1,25 +0,0 @@
From f54ad866c428ecd64a01cfdf7fc6b0a64f5e0fe5 Mon Sep 17 00:00:00 2001
From: Pingfan Liu <piliu@redhat.com>
Date: Tue, 15 Dec 2020 14:13:13 +0800
Subject: [PATCH] fix
---
eppic/libeppic/eppic.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/eppic/libeppic/eppic.h b/eppic/libeppic/eppic.h
index 06320f2..74a3c1c 100644
--- a/eppic/libeppic/eppic.h
+++ b/eppic/libeppic/eppic.h
@@ -467,7 +467,7 @@ type_t *eppic_addstorage(type_t *t1, type_t *t2);
type_t *eppic_getvoidstruct(int ctype);
extern int lineno, needvar, instruct, nomacs, eppic_legacy;
-node_t *lastv;
+extern node_t *lastv;
#define NULLNODE ((node_t*)0)
--
2.29.2

View File

@ -1,89 +0,0 @@
From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
Date: Wed, 18 Dec 2019 11:42:30 -0500
Subject: [PATCH 1/3] kexec: add variant helper functions for handling memory
regions
mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are
functionally equivalent to, respectively, mem_regions_add() and
mem_regions_exclude() except the formers will re-allocate memory
dynamically when no more entries are available in 'ranges' array.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++
kexec/mem_regions.h | 7 +++++++
2 files changed, 49 insertions(+)
diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c
index 50c8abccb93a..ad7d3f13fd84 100644
--- a/kexec/mem_regions.c
+++ b/kexec/mem_regions.c
@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges,
}
return 0;
}
+
+#define KEXEC_MEMORY_RANGES 16
+
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
+ unsigned long long base,
+ unsigned long long length, int type)
+{
+ void *new_ranges;
+
+ if (ranges->size >= ranges->max_size) {
+ new_ranges = realloc(ranges->ranges,
+ sizeof(struct memory_range) *
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
+ if (!new_ranges)
+ return -1;
+
+ ranges->ranges = new_ranges;
+ ranges->max_size += KEXEC_MEMORY_RANGES;
+ }
+
+ return mem_regions_add(ranges, base, length, type);
+}
+
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
+ const struct memory_range *range)
+{
+ void *new_ranges;
+
+ /* for safety, we should have at least one free entry in ranges */
+ if (ranges->size >= ranges->max_size) {
+ new_ranges = realloc(ranges->ranges,
+ sizeof(struct memory_range) *
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
+ if (!new_ranges)
+ return -1;
+
+ ranges->ranges = new_ranges;
+ ranges->max_size += KEXEC_MEMORY_RANGES;
+ }
+
+ return mem_regions_exclude(ranges, range);
+}
diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h
index ae9e972b0206..e306d67e3261 100644
--- a/kexec/mem_regions.h
+++ b/kexec/mem_regions.h
@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges,
int mem_regions_add(struct memory_ranges *ranges, unsigned long long base,
unsigned long long length, int type);
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
+ const struct memory_range *range);
+
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
+ unsigned long long base,
+ unsigned long long length, int type);
+
#endif
--
2.7.4

View File

@ -1,38 +0,0 @@
From a46c686f615a86933134c0924c3391ba598a02b8 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhsharma@redhat.com>
Date: Tue, 10 Sep 2019 15:51:49 +0530
Subject: [PATCH 5/5] vmcore-dmesg/vmcore-dmesg.c: Fix shifting error reported
by cppcheck
Running 'cppcheck' static code analyzer (see cppcheck(1))
on 'vmcore-dmesg/vmcore-dmesg.c' shows the following
shifting error:
$ cppcheck --enable=all vmcore-dmesg/vmcore-dmesg.c
Checking vmcore-dmesg/vmcore-dmesg.c ...
[vmcore-dmesg/vmcore-dmesg.c:17]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour
Fix the same via this patch.
Signed-off-by: Bhupesh Sharma <bhsharma@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 81c2a58c9d86..122e53672e01 100644
--- a/vmcore-dmesg/vmcore-dmesg.c
+++ b/vmcore-dmesg/vmcore-dmesg.c
@@ -6,7 +6,7 @@ typedef Elf32_Nhdr Elf_Nhdr;
extern const char *fname;
/* stole this macro from kernel printk.c */
-#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
+#define LOG_BUF_LEN_MAX (uint32_t)(1U << 31)
static void write_to_stdout(char *buf, unsigned int nr)
{
--
2.17.1

View File

@ -0,0 +1,76 @@
commit 6d0d95ecc04a70f8448d562ff0fbbae237f5c929
Author: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Thu Apr 21 08:58:29 2022 +0900
[PATCH] Avoid false-positive mem_section validation with vmlinux
Currently get_mem_section() validates if SYMBOL(mem_section) is the address
of the mem_section array first. But there was a report that the first
validation wrongly returned TRUE with -x vmlinux and SPARSEMEM_EXTREME
(4.15+) on s390x. This leads to crash failing statup with the following
seek error:
crash: seek error: kernel virtual address: 67fffc2800 type: "memory section root table"
Skip the first validation when satisfying the conditions.
Reported-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Reviewed-and-Tested-by: Philipp Rudo <prudo@redhat.com>
Reviewed-by: Pingfan Liu <piliu@redhat.com>
diff --git a/makedumpfile-1.7.1/makedumpfile.c b/makedumpfile-1.7.1/makedumpfile.c
index a2f45c84cee3ba57ce3d3cf3f1905e6a03f4fd09..65d1c7c2f02c9ae8ead9de0f0217235fe72b3ca7 100644
--- a/makedumpfile-1.7.1/makedumpfile.c
+++ b/makedumpfile-1.7.1/makedumpfile.c
@@ -3698,6 +3698,22 @@ validate_mem_section(unsigned long *mem_sec,
return ret;
}
+/*
+ * SYMBOL(mem_section) varies with the combination of memory model and
+ * its source:
+ *
+ * SPARSEMEM
+ * vmcoreinfo: address of mem_section root array
+ * -x vmlinux: address of mem_section root array
+ *
+ * SPARSEMEM_EXTREME v1
+ * vmcoreinfo: address of mem_section root array
+ * -x vmlinux: address of mem_section root array
+ *
+ * SPARSEMEM_EXTREME v2 (with 83e3c48729d9 and a0b1280368d1) 4.15+
+ * vmcoreinfo: address of mem_section root array
+ * -x vmlinux: address of pointer to mem_section root array
+ */
static int
get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps,
unsigned int num_section)
@@ -3710,12 +3726,27 @@ get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps,
strerror(errno));
return FALSE;
}
+
+ /*
+ * There was a report that the first validation wrongly returned TRUE
+ * with -x vmlinux and SPARSEMEM_EXTREME v2 on s390x, so skip it.
+ * Howerver, leave the fallback validation as it is for the -i option.
+ */
+ if (is_sparsemem_extreme() && info->name_vmlinux) {
+ unsigned long flag = 0;
+ if (get_symbol_type_name("mem_section", DWARF_INFO_GET_SYMBOL_TYPE,
+ NULL, &flag)
+ && !(flag & TYPE_ARRAY))
+ goto skip_1st_validation;
+ }
+
ret = validate_mem_section(mem_sec, SYMBOL(mem_section),
mem_section_size, mem_maps, num_section);
if (!ret && is_sparsemem_extreme()) {
unsigned long mem_section_ptr;
+skip_1st_validation:
if (!readmem(VADDR, SYMBOL(mem_section), &mem_section_ptr,
sizeof(mem_section_ptr)))
goto out;

View File

@ -446,7 +446,3 @@ if ! is_fadump_capable; then
fi
echo "$dracut_args $@" | xargs dracut
_rc=$?
sync
exit $_rc

View File

@ -12,10 +12,10 @@ Signed-off-by: Pingfan Liu <piliu@redhat.com>
makedumpfile.h | 1 +
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/makedumpfile-1.7.0/arch/arm64.c b/makedumpfile-1.7.0/arch/arm64.c
diff --git a/makedumpfile-1.7.1/arch/arm64.c b/makedumpfile-1.7.1/arch/arm64.c
index 1072178..95beae6 100644
--- a/makedumpfile-1.7.0/arch/arm64.c
+++ b/makedumpfile-1.7.0/arch/arm64.c
--- a/makedumpfile-1.7.1/arch/arm64.c
+++ b/makedumpfile-1.7.1/arch/arm64.c
@@ -50,6 +50,7 @@ static int va_bits;
static int vabits_actual;
static int flipped_va;
@ -51,10 +51,10 @@ index 1072178..95beae6 100644
kimage_voffset = NUMBER(kimage_voffset);
info->section_size_bits = SECTIONS_SIZE_BITS;
diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c
diff --git a/makedumpfile-1.7.1/makedumpfile.c b/makedumpfile-1.7.1/makedumpfile.c
index 3ad4443..018ea4c 100644
--- a/makedumpfile-1.7.0/makedumpfile.c
+++ b/makedumpfile-1.7.0/makedumpfile.c
--- a/makedumpfile-1.7.1/makedumpfile.c
+++ b/makedumpfile-1.7.1/makedumpfile.c
@@ -2417,6 +2417,7 @@ write_vmcoreinfo_data(void)
WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
@ -71,10 +71,10 @@ index 3ad4443..018ea4c 100644
READ_NUMBER("VA_BITS", VA_BITS);
READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ);
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
diff --git a/makedumpfile-1.7.0/makedumpfile.h b/makedumpfile-1.7.0/makedumpfile.h
diff --git a/makedumpfile-1.7.1/makedumpfile.h b/makedumpfile-1.7.1/makedumpfile.h
index e59239d..b6236dd 100644
--- a/makedumpfile-1.7.0/makedumpfile.h
+++ b/makedumpfile-1.7.0/makedumpfile.h
--- a/makedumpfile-1.7.1/makedumpfile.h
+++ b/makedumpfile-1.7.1/makedumpfile.h
@@ -2064,6 +2064,7 @@ struct number_table {
long phys_base;
long KERNEL_IMAGE_SIZE;

View File

@ -1,6 +1,6 @@
Name: kexec-tools
Version: 2.0.20
Release: 69%{?dist}
Version: 2.0.24
Release: 1%{?dist}
License: GPLv2
Group: Applications/System
Summary: The kexec/kdump userspace component
@ -13,7 +13,7 @@ Source4: kdump.sysconfig.i386
Source5: kdump.sysconfig.ppc64
Source7: mkdumprd
Source8: kdump.conf
Source9: https://github.com/makedumpfile/makedumpfile/archive/1.7.0.tar.gz
Source9: https://github.com/makedumpfile/makedumpfile/archive/1.7.1.tar.gz
Source10: kexec-kdump-howto.txt
Source12: mkdumprd.8
Source13: 98-kexec.rules
@ -98,11 +98,6 @@ ExcludeArch: i686
#
# Patches 401 through 500 are meant for s390 kexec-tools enablement
#
Patch401: ./kexec-tools-2.0.20-01-s390_add_variable_command_line_size.patch
Patch402: ./kexec-tools-2.0.20-02-s390_use_KEXEC_ALL_OPTIONS.patch
Patch403: ./kexec-tools-2.0.20-03-add_slurp_proc_file_.patch
Patch404: ./kexec-tools-2.0.20-04-use_slurp_proc_file_in_get_command_line_.patch
Patch405: ./kexec-tools-2.0.20-05-s390_add_support_for_reuse_cmdline.patch
#
# Patches 501 through 600 are meant for ARM kexec-tools enablement
@ -113,29 +108,10 @@ Patch405: ./kexec-tools-2.0.20-05-s390_add_support_for_reuse_cmdline.patch
#
Patch601: rhelonly-kexec-tools-2.0.16-koji-build-fail-workaround.patch
Patch602: rhelonly-kexec-tools-2.0.18-eppic-fix-issues-with-hardening-flags.patch
#Patch603: rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch
Patch604: kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch
Patch605: kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch
Patch606: kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch
Patch607: kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch
Patch608: kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch
Patch609: kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch
Patch610: kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch
Patch611: kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch
Patch612: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch
Patch613: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch
Patch614: kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch
Patch615: kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch
Patch616: kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch
Patch617: kexec-tools-2.0.20-05-util_lib_elf_info_harden_parsing_of_printk_buffer.patch
# Patches 701 onward for makedumpfile
Patch701: rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch
Patch702: kexec-tools-2.0.20-01-_PATCH_v2_1_3_add_generic_cycle_detection.patch
Patch703: kexec-tools-2.0.20-02-_PATCH_v2_2_3_use_pointer_arithmetics_for_dump_dmesg.patch
Patch704: kexec-tools-2.0.20-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch
Patch705: kexec-tools-2.0.20-04-_PATCH_print_error_when_reading_with_unsupported_compression.patch
Patch702: kexec-tools-2.0.24-makedumpfile-Avoid_false_positive_mem_section_validation_with_vmlinux.patch
%description
kexec-tools provides /usr/sbin/kexec binary that facilitates a new
@ -151,34 +127,11 @@ mkdir -p -m755 kcp
tar -z -x -v -f %{SOURCE9}
tar -z -x -v -f %{SOURCE19}
%patch401 -p1
%patch402 -p1
%patch403 -p1
%patch404 -p1
%patch405 -p1
%patch601 -p1
%patch602 -p1
#%patch603 -p1
%patch604 -p1
%patch605 -p1
%patch606 -p1
%patch607 -p1
%patch608 -p1
%patch609 -p1
%patch610 -p1
%patch611 -p1
%patch612 -p1
%patch613 -p1
%patch614 -p1
%patch615 -p1
%patch616 -p1
%patch617 -p1
%patch701 -p1
%patch702 -p1
%patch703 -p1
%patch704 -p1
%patch705 -p1
%ifarch ppc
%define archdef ARCH=ppc
@ -208,8 +161,8 @@ cp %{SOURCE31} .
make
%ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64
make -C eppic/libeppic
make -C makedumpfile-1.7.0 LINKTYPE=dynamic USELZO=on USESNAPPY=on USEZSTD=on
make -C makedumpfile-1.7.0 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so
make -C makedumpfile-1.7.1 LINKTYPE=dynamic USELZO=on USESNAPPY=on USEZSTD=on
make -C makedumpfile-1.7.1 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so
%endif
%install
@ -270,13 +223,13 @@ install -m 755 -D %{SOURCE32} $RPM_BUILD_ROOT%{_prefix}/lib/kernel/install.d/60-
%ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64
install -m 755 makedumpfile-1.7.0/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile
install -m 644 makedumpfile-1.7.0/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz
install -m 644 makedumpfile-1.7.0/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz
install -m 644 makedumpfile-1.7.0/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample
install -m 755 makedumpfile-1.7.0/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so
install -m 755 makedumpfile-1.7.1/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile
install -m 644 makedumpfile-1.7.1/makedumpfile.8 $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8
install -m 644 makedumpfile-1.7.1/makedumpfile.conf.5 $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5
install -m 644 makedumpfile-1.7.1/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample
install -m 755 makedumpfile-1.7.1/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so
mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/
install -m 644 makedumpfile-1.7.0/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/
install -m 644 makedumpfile-1.7.1/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/
%endif
%define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g')
@ -440,6 +393,12 @@ done
%endif
%changelog
* Thu May 5 2022 Pingfan Liu <piliu@redhat.com> - 2.0.24-1
- kdumpctl: sync the $TARGET_INITRD after rebuild
- Avoid false-positive mem_section validation with vmlinux
- Rebase kexec-tools to 2.0.24
- Rebase makedumpfile to 1.7.1
* Fri Apr 15 2022 Pingfan Liu <piliu@redhat.com> - 2.0.20-69
- s390: add support for --reuse-cmdline
- use slurp_proc_file() in get_command_line()