Resending because my previous post is held for presumably being sent
without a list subscription.
Since Linux kernel commit 0935288c6e00 ("kdump: append kernel build-id
string to VMCOREINFO") merged in v5.9, VMCOREINFO data contains a kernel
build-id. Add a simple --build-id command line option that retrieves the
build-id from a kernel dump file, which works just like the existing
--osrelease option (and the implementation mimics it).
Example:
# crash --build-id /var/crash/127.0.0.1-2025-11-28-00\:33\:07/vmcore
03cc3b4eb67df4e66a6a794a39521bafabef0886
While we may also want to implement the strict build-id based
verification between namelist and dump file, this would be still handy
for some scripting or automation tasks without namelist.
Signed-off-by: Munehisa Kamata <kamatam(a)amazon.com>
---
crash.8 | 7 +++++++
defs.h | 1 +
diskdump.c | 17 +++++++++++++++++
help.c | 6 ++++++
main.c | 30 ++++++++++++++++++++++++++++++
makedumpfile.c | 40 ++++++++++++++++++++++++++++++++++------
netdump.c | 17 +++++++++++++++++
7 files changed, 112 insertions(+), 6 deletions(-)
diff --git a/crash.8 b/crash.8
index c7dc27d..4c06cb7 100644
--- a/crash.8
+++ b/crash.8
@@ -398,6 +398,13 @@ Display the OSRELEASE vmcoreinfo string from a kdump
.I dumpfile
header.
.TP
+.BI --build-id \ dumpfile
+Display the BUILD-ID vmcoreinfo string from a kdump
+.I dumpfile
+header.
+Note: this option only works for kernel (>=v5.9); otherwise it
+prints "unknown" and exits with non-zero status.
+.TP
.BI --hyper
Force the session to be that of a Xen hypervisor.
.TP
diff --git a/defs.h b/defs.h
index 24dad93..ff8041c 100644
--- a/defs.h
+++ b/defs.h
@@ -570,6 +570,7 @@ struct program_context {
#define MEMSRC_LOCAL (0x80000ULL)
#define REDZONE (0x100000ULL)
#define VMWARE_VMSS_GUESTDUMP (0x200000ULL)
+#define GET_BUILD_ID (0x400000ULL)
char *cleanup;
char *namelist_orig;
char *namelist_debug_orig;
diff --git a/diskdump.c b/diskdump.c
index b1ca0a7..0ff8782 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -91,6 +91,7 @@ static void dump_vmcoreinfo(FILE *);
static void dump_note_offsets(FILE *);
static char *vmcoreinfo_read_string(const char *);
static void diskdump_get_osrelease(void);
+static void diskdump_get_build_id(void);
static int valid_note_address(unsigned char *);
/* For split dumpfile */
@@ -1074,6 +1075,9 @@ is_diskdump(char *file)
if (pc->flags2 & GET_OSRELEASE)
diskdump_get_osrelease();
+ if (pc->flags2 & GET_BUILD_ID)
+ diskdump_get_build_id();
+
#ifdef LZO
if (lzo_init() == LZO_E_OK)
dd->flags |= LZO_SUPPORTED;
@@ -2446,6 +2450,19 @@ diskdump_get_osrelease(void)
pc->flags2 &= ~GET_OSRELEASE;
}
+static void
+diskdump_get_build_id(void)
+{
+ char *string;
+
+ if ((string = vmcoreinfo_read_string("BUILD-ID"))) {
+ fprintf(fp, "%s\n", string);
+ free(string);
+ }
+ else
+ pc->flags2 &= ~GET_BUILD_ID;
+}
+
static int
valid_note_address(unsigned char *offset)
{
diff --git a/help.c b/help.c
index 78d7a5c..1a21062 100644
--- a/help.c
+++ b/help.c
@@ -266,6 +266,12 @@ char *program_usage_info[] = {
" Display the OSRELEASE vmcoreinfo string from a kdump dumpfile",
" header.",
"",
+ " --build-id dumpfile",
+ " Display the BUILD-ID vmcoreinfo string from a kdump dumpfile",
+ " header.",
+ " Note: this option only works for kernel(>=v5.9); otherwise it",
+ " prints \"unknown\" and exits with non-zero status",
+ "",
" --hyper",
" Force the session to be that of a Xen hypervisor.",
"",
diff --git a/main.c b/main.c
index 71bcc15..d4c335b 100644
--- a/main.c
+++ b/main.c
@@ -29,6 +29,7 @@ static void check_xen_hyper(void);
static void show_untrusted_files(void);
static void get_osrelease(char *);
static void get_log(char *);
+static void get_build_id(char *);
static struct option long_options[] = {
{"memory_module", required_argument, 0, 0},
@@ -66,6 +67,7 @@ static struct option long_options[] = {
{"no_elf_notes", 0, 0, 0},
{"osrelease", required_argument, 0, 0},
{"log", required_argument, 0, 0},
+ {"build-id", required_argument, 0, 0},
{"hex", 0, 0, 0},
{"dec", 0, 0, 0},
{"no_strip", 0, 0, 0},
@@ -276,6 +278,11 @@ main(int argc, char **argv)
get_log(optarg);
}
+ else if (STREQ(long_options[option_index].name, "build-id")) {
+ pc->flags2 |= GET_BUILD_ID;
+ get_build_id(optarg);
+ }
+
else if (STREQ(long_options[option_index].name, "hex")) {
pc->flags2 |= RADIX_OVERRIDE;
pc->output_radix = 16;
@@ -1502,6 +1509,8 @@ dump_program_context(void)
fprintf(fp, "%sREDZONE", others++ ? "|" : "");
if (pc->flags2 & VMWARE_VMSS_GUESTDUMP)
fprintf(fp, "%sVMWARE_VMSS_GUESTDUMP", others++ ? "|" :
"");
+ if (pc->flags2 & GET_BUILD_ID)
+ fprintf(fp, "%sGET_BUILD_ID", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " namelist: %s\n", pc->namelist);
@@ -1972,6 +1981,27 @@ get_log(char *dumpfile)
clean_exit(retval);
}
+static void
+get_build_id(char *dumpfile)
+{
+ int retval = 1;
+
+ if (is_flattened_format(dumpfile)) {
+ if (pc->flags2 & GET_BUILD_ID)
+ retval = 0;
+ } else if (is_diskdump(dumpfile)) {
+ if (pc->flags2 & GET_BUILD_ID)
+ retval = 0;
+ } else if (is_kdump(dumpfile, KDUMP_LOCAL)) {
+ if (pc->flags2 & GET_BUILD_ID)
+ retval = 0;
+ }
+
+ if (retval)
+ fprintf(fp, "unknown\n");
+
+ clean_exit(retval);
+}
char *
no_vmcoreinfo(const char *unused)
diff --git a/makedumpfile.c b/makedumpfile.c
index 26d12b6..ee03199 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -24,6 +24,7 @@
#include <byteswap.h>
static void flattened_format_get_osrelease(char *);
+static void flattened_format_get_build_id(char *);
int flattened_format = 0;
@@ -196,7 +197,7 @@ read_all_makedumpfile_data_header(char *file)
void
check_flattened_format(char *file)
{
- int fd, get_osrelease;
+ int fd, get_osrelease, get_build_id;
struct stat stat;
struct makedumpfile_header fh;
@@ -206,6 +207,12 @@ check_flattened_format(char *file)
} else
get_osrelease = FALSE;
+ if (pc->flags2 & GET_BUILD_ID) {
+ get_build_id = TRUE;
+ pc->flags2 &= ~GET_BUILD_ID;
+ } else
+ get_build_id = FALSE;
+
if (flattened_format)
goto out;
@@ -237,6 +244,11 @@ check_flattened_format(char *file)
return;
}
+ if (get_build_id) {
+ flattened_format_get_build_id(file);
+ return;
+ }
+
if (!read_all_makedumpfile_data_header(file))
return;
@@ -251,6 +263,9 @@ check_flattened_format(char *file)
out:
if (get_osrelease)
pc->flags2 |= GET_OSRELEASE;
+
+ if (get_build_id)
+ pc->flags2 |= GET_BUILD_ID;
}
static int
@@ -368,26 +383,39 @@ dump_flat_header(FILE *ofp)
}
static void
-flattened_format_get_osrelease(char *file)
+flattened_format_get_common(char *file, char *key, ulonglong flag)
{
int c;
FILE *pipe;
- char buf[BUFSIZE], *p1, *p2;
+ char keybuf[BUFSIZE], buf[BUFSIZE], *p1, *p2;
- c = strlen("OSRELEASE=");
+ sprintf(keybuf, "%s=", key);
+ c = strlen(keybuf);
sprintf(buf, "/usr/bin/strings -n %d %s", c, file);
if ((pipe = popen(buf, "r")) == NULL)
return;
for (c = 0; (c < 100) && fgets(buf, BUFSIZE-1, pipe); c++) {
- if ((p1 = strstr(buf, "OSRELEASE="))) {
+ if ((p1 = strstr(buf, keybuf))) {
p2 = strstr(p1, "=");
fprintf(fp, "%s", p2+1);
flattened_format = TRUE;
- pc->flags2 |= GET_OSRELEASE;
+ pc->flags2 |= flag;
}
}
pclose(pipe);
}
+
+static void
+flattened_format_get_osrelease(char *file)
+{
+ flattened_format_get_common(file, "OSRELEASE", GET_OSRELEASE);
+}
+
+static void
+flattened_format_get_build_id(char *file)
+{
+ flattened_format_get_common(file, "BUILD-ID", GET_BUILD_ID);
+}
diff --git a/netdump.c b/netdump.c
index c7ff009..ba1c6c4 100644
--- a/netdump.c
+++ b/netdump.c
@@ -50,6 +50,7 @@ static int proc_kcore_init_64(FILE *, int);
static char *get_regs_from_note(char *, ulong *, ulong *);
static void kdump_get_osrelease(void);
static char *vmcoreinfo_read_string(const char *);
+static void kdump_get_build_id(void);
#define ELFSTORE 1
@@ -477,6 +478,10 @@ is_netdump(char *file, ulong source_query)
get_log_from_vmcoreinfo(file);
}
+ if ((source_query == KDUMP_LOCAL) &&
+ (pc->flags2 & GET_BUILD_ID))
+ kdump_get_build_id();
+
return nd->header_size;
bailout:
@@ -4996,6 +5001,18 @@ kdump_get_osrelease(void)
pc->flags2 &= ~GET_OSRELEASE;
}
+static void
+kdump_get_build_id(void)
+{
+ char *string;
+
+ if ((string = vmcoreinfo_read_string("BUILD-ID"))) {
+ fprintf(fp, "%s\n", string);
+ free(string);
+ } else
+ pc->flags2 &= ~GET_BUILD_ID;
+}
+
void
dump_registers_for_qemu_mem_dump(void)
{
--
2.47.3