Date: Mon, 10 Nov 2014 22:54:51 -0800 From: Mark Johnston <markj@FreeBSD.org> To: freebsd-arch@freebsd.org Subject: [RFC] core dump compression Message-ID: <20141111065451.GA9757@raichu>
next in thread | raw e-mail | index | archive | help
Hello, It's possible to have the kernel write out userland core dumps as gzip files, provided that the COMPRESS_USER_CORES option is present in the kernel. Currently this feature doesn't work properly because of some locking changes introduced in r272535. It's easy to fix this directly by adding IO_RANGELOCKED to the flags of the vn_rdwr_inchunks() calls in kern_gzio.c, but this approach seems somewhat hacky - kern_gzio.c is ostensibly a general-purpose interface (it's enabled by "device gzio" in the kernel config), so modifying the flags is wrong. I rewrote kern_gzio.c to provide a small callback-based interface to the in-kernel zlib, and changed the userland core dump code to use it. Together with this is a patch which optionally enables the kernel to compress its own core dumps as they're written out to the dump device. The idea is to make it more likely that we'll be able to fit a core on the dump device (which is often the swap partition for the system). The patches are available at: https://people.freebsd.org/~markj/patches/core-compression/20141110-kern_gzio.diff and https://people.freebsd.org/~markj/patches/core-compression/20141110-kern_dump.diff The first fixes userland core dump compression. It replaces the gzio device and COMPRESS_USER_CORES option with a GZIO option. When the kernel is compiled with this option, the kern.compress_user_cores sysctl determines whether userland core dumps will be compressed (defaulting to off). The second patch adds kern_dump.c, which provides a small interface for use by the MD kernel core dump code (i.e. dumpsys() and minidumpsys()). Its purpose is to hide the details of where the dump gets written on the dump device. Normally, dumpsys/minidumpsys computes the total size of the dump ahead of time, and writes it out so that the end of the dump coincides with the end of the device. With compression this isn't possible, since we can't know the final size ahead of time. The approach I've taken is to write the dump starting at the same offset an uncompressed dump would use. Once that's done, the headers are written to the beginning of the dump and the end of the device, and savecore(8) has been taught to detect compressed dumps and recover them. With the patch, kern_dump.c becomes responsible for writing the headers and for keeping track of the current offset within the dump; this lets us remove quite a bit of duplicated code from the various dumpsys/minidumpsys implementations without introducing any complexity in the !compressed case. For core dump compression, kern_dump.c uses the GZIO interface; the callback just calls dump_write() to write the compressed data to disk. With the second patch, kernel core dump compression is enabled using the kern.compress_kernel_dumps sysctl/tunable. At the moment it can only be set as a tunable, but I'll fix this soon. In practice, the compression factor that we get is between 6 and 14, with worse compression for larger cores. On the several amd64 systems that I've tested, the time required to actually write a core is increased slightly; on the other hand, a savecore(8) for a compressed dump is obviously much faster, so the boot following a crash will complete more quickly. The patches are still a bit rough, but I was hoping for some feedback on the approach and the new interfaces defined in kern_dump.c and kern_gzio.c. I've tested on a number of physical systems and VMs without any problems - further testing is very welcome, particularly on non-x86 systems. Thanks! -Mark
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20141111065451.GA9757>