diff options
Diffstat (limited to 'vmcore-dmesg')
-rw-r--r-- | vmcore-dmesg/Makefile | 29 | ||||
-rw-r--r-- | vmcore-dmesg/vmcore-dmesg.8 | 42 | ||||
-rw-r--r-- | vmcore-dmesg/vmcore-dmesg.c | 69 |
3 files changed, 140 insertions, 0 deletions
diff --git a/vmcore-dmesg/Makefile b/vmcore-dmesg/Makefile new file mode 100644 index 0000000..b147f26 --- /dev/null +++ b/vmcore-dmesg/Makefile @@ -0,0 +1,29 @@ +# +# vmcore-dmesg (reading demsg from vmcore) +# + +VMCORE_DMESG_SRCS:= vmcore-dmesg/vmcore-dmesg.c + +VMCORE_DMESG_OBJS = $(call objify, $(VMCORE_DMESG_SRCS)) +VMCORE_DMESG_DEPS = $(call depify, $(VMCORE_DMESG_OBJS)) + +VMCORE_DMESG = $(SBINDIR)/vmcore-dmesg +VMCORE_DMESG_MANPAGE = $(MANDIR)/man8/vmcore-dmesg.8 + +dist += vmcore-dmesg/Makefile $(VMCORE_DMESG_SRCS) vmcore-dmesg/vmcore-dmesg.8 +clean += $(VMCORE_DMESG_OBJS) $(VMCORE_DMESG_DEPS) $(VMCORE_DMESG) $(VMCORE_DMESG_MANPAGE) + +-include $(VMCORE_DMESG_DEPS) + +$(VMCORE_DMESG): $(VMCORE_DMESG_OBJS) $(UTIL_LIB) + @$(MKDIR) -p $(@D) + $(LINK.o) -o $@ $^ $(CFLAGS) $(LIBS) + +$(VMCORE_DMESG_MANPAGE): vmcore-dmesg/vmcore-dmesg.8 + $(MKDIR) -p $(MANDIR)/man8 + cp $^ $(VMCORE_DMESG_MANPAGE) +echo:: + @echo "VMCORE_DMESG_SRCS $(VMCORE_DMESG_SRCS)" + @echo "VMCORE_DMESG_DEPS $(VMCORE_DMESG_DEPS)" + @echo "VMCORE_DMESG_OBJS $(VMCORE_DMESG_OBJS)" + diff --git a/vmcore-dmesg/vmcore-dmesg.8 b/vmcore-dmesg/vmcore-dmesg.8 new file mode 100644 index 0000000..ec594b0 --- /dev/null +++ b/vmcore-dmesg/vmcore-dmesg.8 @@ -0,0 +1,42 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH VMCORE-DMESG 8 "Sep 21, 2020" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +vmcore-dmesg +.SH SYNOPSIS +.B vmcore-dmesg +.RI " vmcore" +.SH DESCRIPTION +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBvmcore-dmesg\fP extracts the dmesg from a vmcore and write it to +standard out. \fBvmcore-dmesg\fP works against either +\fB/proc/vmcore\fP in a crash dump capture context or a copy +of \fB/proc/vmcore\fP that has been saved for later analysis. A +single build of \fBvmcore-dmesg\fP should work against any linux +vmcore written created on any architecture. + +.\"These programs follow the usual GNU command line syntax, with long +.\"options starting with two dashes (`-'). +.\"A summary of options is included below. +.\"For a complete description, see the Info files. +.SH SEE ALSO +kexec(8) +.SH AUTHOR +vmcore-dmesg was written by Eric Biederman. diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c new file mode 100644 index 0000000..122e536 --- /dev/null +++ b/vmcore-dmesg/vmcore-dmesg.c @@ -0,0 +1,69 @@ +#include <elf_info.h> + +/* The 32bit and 64bit note headers make it clear we don't care */ +typedef Elf32_Nhdr Elf_Nhdr; + +extern const char *fname; + +/* stole this macro from kernel printk.c */ +#define LOG_BUF_LEN_MAX (uint32_t)(1U << 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) { + 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; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s <kernel core file>\n", argv[0]); + return 1; + } + fname = argv[1]; + + fd = open(fname, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open %s: %s\n", + fname, strerror(errno)); + return 2; + } + + ret = read_vmcore_dmesg(fd, write_to_stdout); + + close(fd); + + return ret; +} |