} while (0)
static int process_kmsg(struct dmesg_control *ctl);
+static int process_kmsg_file(struct dmesg_control *ctl, char **buf);
static int set_level_color(int log_level, const char *mesg, size_t mesgsz)
{
fputs(_(" -D, --console-off disable printing messages to console\n"), out);
fputs(_(" -E, --console-on enable printing messages to console\n"), out);
fputs(_(" -F, --file <file> use the file instead of the kernel log buffer\n"), out);
+ fputs(_(" -K, --kmsg-file <file> use the file in kmsg format\n"), out);
fputs(_(" -f, --facility <list> restrict output to defined facilities\n"), out);
fputs(_(" -H, --human human readable output\n"), out);
fputs(_(" -J, --json use JSON output format\n"), out);
n = read_syslog_buffer(ctl, buf);
break;
case DMESG_METHOD_KMSG:
- /*
- * Since kernel 3.5.0
- */
- n = process_kmsg(ctl);
+ if (ctl->filename)
+ n = process_kmsg_file(ctl, buf);
+ else
+ /*
+ * Since kernel 3.5.0
+ */
+ n = process_kmsg(ctl);
break;
default:
abort(); /* impossible method -> drop core */
return 0;
}
+static int process_kmsg_file(struct dmesg_control *ctl, char **buf)
+{
+ char str[sizeof(ctl->kmsg_buf)];
+ struct dmesg_record rec;
+ ssize_t sz;
+ size_t len;
+
+ if (ctl->method != DMESG_METHOD_KMSG || !ctl->filename)
+ return -1;
+
+ sz = mmap_file_buffer(ctl, buf);
+ if (sz == -1)
+ return -1;
+
+ while (sz > 0) {
+ len = strnlen(ctl->mmap_buff, sz);
+ if (len > sizeof(str))
+ errx(EXIT_FAILURE, _("record too large"));
+
+ memcpy(str, ctl->mmap_buff, len);
+
+ if (parse_kmsg_record(ctl, &rec, str, len) == 0)
+ print_record(ctl, &rec);
+
+ if (len < (size_t)sz)
+ len++;
+
+ sz -= len;
+ ctl->mmap_buff += len;
+ }
+
+ return 0;
+}
+
static int which_time_format(const char *s)
{
if (!strcmp(s, "notime"))
{ "help", no_argument, NULL, 'h' },
{ "json", no_argument, NULL, 'J' },
{ "kernel", no_argument, NULL, 'k' },
+ { "kmsg-file", required_argument, NULL, 'K' },
{ "level", required_argument, NULL, 'l' },
{ "since", required_argument, NULL, OPT_SINCE },
{ "syslog", no_argument, NULL, 'S' },
static const ul_excl_t excl[] = { /* rows and cols in ASCII order */
{ 'C','D','E','c','n','r' }, /* clear,off,on,read-clear,level,raw*/
+ { 'F','K' }, /* file, kmsg-file */
{ 'H','r' }, /* human, raw */
{ 'L','r' }, /* color, raw */
{ 'S','w' }, /* syslog,follow */
textdomain(PACKAGE);
close_stdout_atexit();
- while ((c = getopt_long(argc, argv, "CcDdEeF:f:HhJkL::l:n:iPprSs:TtuVWwx",
+ while ((c = getopt_long(argc, argv, "CcDdEeF:f:HhJK:kL::l:n:iPprSs:TtuVWwx",
longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
ctl.filename = optarg;
ctl.method = DMESG_METHOD_MMAP;
break;
+ case 'K':
+ ctl.filename = optarg;
+ ctl.method = DMESG_METHOD_KMSG;
+ break;
case 'f':
ctl.fltr_fac = 1;
if (string_to_bitarray(optarg,
switch (ctl.action) {
case SYSLOG_ACTION_READ_ALL:
case SYSLOG_ACTION_READ_CLEAR:
- if (ctl.method == DMESG_METHOD_KMSG && init_kmsg(&ctl) != 0)
+ if (ctl.method == DMESG_METHOD_KMSG && !ctl.filename && init_kmsg(&ctl) != 0)
ctl.method = DMESG_METHOD_SYSLOG;
if (ctl.raw
--- /dev/null
+{
+ "dmesg": [
+ {
+ "pri": 5,
+ "time": 0.000000,
+ "msg": "Linux version 6.6.4-arch1-1 (linux@archlinux) (gcc (GCC) 13.2.1 20230801, GNU ld (GNU Binutils) 2.41.0) #1 SMP PREEMPT_DYNAMIC Mon, 04 Dec 2023 00:29:19 +0000"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "Command line: initrd=\\ucode.img initrd=\\initramfs-linux.img rw cryptdevice=/dev/nvme0n1p3:system:discard root=/dev/mapper/system"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-provided physical RAM map:"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000000000000-0x000000000009efff] usable"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x000000000009f000-0x00000000000bffff] reserved"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000000100000-0x0000000009afffff] usable"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000009b00000-0x0000000009dfffff] reserved"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000009e00000-0x0000000009efffff] usable"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000009f00000-0x0000000009f3bfff] ACPI NVS"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000009f3c000-0x000000004235ffff] usable"
+ },{
+ "pri": 6,
+ "time": 0.000000,
+ "msg": "BIOS-e820: [mem 0x0000000042360000-0x000000004455ffff] reserved"
+ },{
+ "pri": 6,
+ "time": 0.367657,
+ "msg": "ACPI: \\_SB_.PCI0.GP19.NHI1.PWRS: New power resource"
+ },{
+ "pri": 6,
+ "time": 0.368615,
+ "msg": "ACPI: \\_SB_.PCI0.GP19.XHC4.PWRS: New power resource"
+ },{
+ "pri": 6,
+ "time": 0.376316,
+ "msg": "ACPI: \\_SB_.PRWL: New power resource"
+ },{
+ "pri": 6,
+ "time": 0.376343,
+ "msg": "ACPI: \\_SB_.PRWB: New power resource"
+ },{
+ "pri": 6,
+ "time": 0.377373,
+ "msg": "ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])"
+ },{
+ "pri": 6,
+ "time": 0.377378,
+ "msg": "acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI EDR HPX-Type3]"
+ },{
+ "pri": 6,
+ "time": 0.377569,
+ "msg": "acpi PNP0A08:00: _OSC: platform does not support [SHPCHotplug AER]"
+ },{
+ "pri": 6,
+ "time": 0.377933,
+ "msg": "acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME PCIeCapability LTR DPC]"
+ },{
+ "pri": 6,
+ "time": 0.378458,
+ "msg": "PCI host bridge to bus 0000:00"
+ },{
+ "pri": 6,
+ "time": 0.378459,
+ "msg": "pci_bus 0000:00: root bus resource [io 0x0000-0x0cf7 window]"
+ },{
+ "pri": 6,
+ "time": 0.378461,
+ "msg": "pci_bus 0000:00: root bus resource [io 0x0d00-0xffff window]"
+ }
+ ]
+}