RFC Support dumps without VMCOREINFO
Motivation
For instance kernel dumps from Qemu hypervisor in the ELF format may miss VMCOREINFO
(qemu) dump-guest-memory /tmp/qemudump
Before
$ DRGN_USE_LIBKDUMPFILE_FOR_ELF=1 drgn -c /tmp/qemudump -s ~/tmp/kbuild-ci/6.14.0/vmlinux
drgn 0.0.30+51.ga0990649 (using Python 3.11.11, elfutils 0.192, with libkdumpfile)
error: unrecognized QEMU memory dump; for Linux guests, run QEMU with '-device vmcoreinfo', compile the kernel with CONFIG_FW_CFG_SYSFS and CONFIG_KEXEC, and load the qemu_fw_cfg kernel module before dumping the guest memory (requires Linux >= 4.17 and QEMU >= 2.11)
After
$ DRGN_USE_LIBKDUMPFILE_FOR_ELF=1 drgn --log-level=info -c /tmp/qemudump -s ~/tmp/kbuild-ci/6.14.0/vmlinux
drgn 0.0.30+58.gb0133939 (using Python 3.11.11, elfutils 0.192, with libkdumpfile)
warning: No vmcoreinfo (linux.vmcoreinfo.raw is not set), relying on addrxlat and debuginfo
info: Calculated ktext_offset=39000000
info: kernel: using debug info file .../kbuild-ci/6.14.0/vmlinux
warning: missing debugging symbols for virtio_rng
warning: missing some debugging symbols; see https://drgn.readthedocs.io/en/latest/getting_debugging_symbols.html
For help, type help(drgn).
>>> import drgn
>>> from drgn import FaultError, NULL, Object, alignof, cast, container_of, execscript, implicit_convert, offsetof, reinterpret, sizeof, stack_trace
>>> from drgn.helpers.common import *
>>> from drgn.helpers.linux import *
>>> prog['init_task'].comm
(char [16])"swapper/0"
Summary
- this relaxes requirement on having VMCOREINFO, the main issue is figuring out KASLR offset, thanks to libaddrxlat (libkdumpfile) it is possible to calculate it
- it's possible to work with dumps in ELF format from Qemu that typically miss this info
- implementation is rather bolted on && I haven't sanitized all possible uses of (formerly mandatory) values from VMCOREINFO
- this is RFC to know whether this is something to pursue further
So this is a really interesting strategy. Thanks for this PR! I guess libkdumpfile is getting the kernel text location by inferring some things from the page tables, in the cases where the vmcoreinfo and other metadata is missing. At least, that's what I'm getting from the following code:
https://github.com/ptesarik/libkdumpfile/blob/3fcff045bba4a1443aa53abc19eda89d741b3fe2/src/addrxlat/x86_64.c#L388
I am a big fan of anything that allows better support for vmcores where the VMCOREINFO is missing or not easy to find. That said, we would probably need to take a careful look at areas that expect the values of OSRELEASE, PAGE_SIZE, CRASHTIME, and swapper_pg_dir to exist (as you noted in the code).
In these cases, I've usually found that the issue is not so much that the VMCOREINFO is totally unavailable. It's always there in kernel memory. It's just that QEMU (or some other core dump producer) doesn't know about it. It's still buried in the kernel memory, and thus it's still present in the vmcore. But with a libkdumpfile program like this one, it's possible to search the vmcore page by page and find the data that is most likely the vmcoreinfo note. Then, you can provide that when creating the program, or with the --vmcoreinfo argument to the drgn CLI. The benefit of this is that you still get all of the metadata provided by the VMCOREINFO note. The downside of course that it's more work for the user, and it's also possible that the data you thought was the VMCOREINFO was actually a false positive.
So I wonder if we can combine the benefit of both approaches? Yours identifies the kernel text location, and if you have the vmlinux file handy, then you can use that to derive the KASLR offset. From that, you can get the address of vmcoreinfo_data, and from there you can read the vmcoreinfo note itself. At this point, you can read it out of the vmcore and fill in the struct in the struct drgn_program, thus avoiding all the issues with missing data!
I have a few questions for you:
- Does this approach work with the kdump formatted vmcores? Or just ELF? I haven't found ELF core dumps to be a particularly popular format for QEMU dumps, due to the lack of compression.
- Have you tried the approach with extracting the vmcoreinfo I described above? Does it work for your needs?
Currently, it only works with ELF (which was my recent use case) but it shouldn't be that hard to utilize the same for kdump vmcores. I considered searching vmcoreinfo in raw data initially but when I learnt that libxattr seems to work alone, I abandoned that -- but I agree it'd be good to combine both sources. (Only quick answers, I understand this isn't perceived vain but I'll get down to this again only some time later ;-))