import kexec-tools-2.0.24-1.el8
This commit is contained in:
parent
dbf4d4a69b
commit
3244c72eda
4
.gitignore
vendored
4
.gitignore
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
@ -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 */
|
@ -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;
|
@ -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 "";
|
@ -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;
|
||||
}
|
@ -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
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
@ -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"
|
||||
);
|
||||
}
|
@ -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)
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -446,7 +446,3 @@ if ! is_fadump_capable; then
|
||||
fi
|
||||
|
||||
echo "$dracut_args $@" | xargs dracut
|
||||
|
||||
_rc=$?
|
||||
sync
|
||||
exit $_rc
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user