[RFC] makedumpfile, crash: LZO compression support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

This is a RFC patch set that adds LZO compression support to
makedumpfile and crash utility. LZO is as good as in size but by far
better in speed than ZLIB, leading to reducing down time during
generation of crash dump and refiltering.

How to build:

  1. Get LZO library, which is provided as lzo-devel package on recent
  linux distributions, and is also available on author's website:
  http://www.oberhumer.com/opensource/lzo/.

  2. Apply the patch set to makedumpfile v1.4.0 and crash v6.0.0.

  3. Build both using make. But for crash, do the following now:

    $ make CFLAGS="-llzo2"

How to use:

  I've newly used -l option for lzo compression in this patch. So for
  example, do as follows:

  $ makedumpfile -l vmcore dumpfile
  $ crash vmlinux dumpfile

Request of configure-like feature for crash utility:

  I would like configure-like feature on crash utility for users to
  select wheather to add LZO feature actually or not in build-time,
  that is: ./configure --enable-lzo or ./configure --disable-lzo.

  The reason is that support staff often downloads and installs the
  latest version of crash utility on machines where lzo library is not
  provided.

  Looking at the source code, it looks to me that crash does some kind
  of configuration processing in a local manner, around configure.c,
  and I guess it's difficult to use autoconf tools directly.

  Or is there another better way?

Performance Comparison:

  Sample Data

    Ideally, I must have measured the performance for many enough
    vmcores generated from machines that was actually running, but now
    I don't have enough sample vmcores, I couldn't do so. So this
    comparison doesn't answer question on I/O time improvement. This
    is TODO for now.

    Instead, I choosed worst and best cases regarding compression
    ratio and speed only. Specifically, the former is /dev/urandom and
    the latter is /dev/zero.

    I get the sample data of 10MB, 100MB and 1GB by doing like this:

      $ dd bs=4096 count=$((1024*1024*1024/4096)) if=/dev/urandom of=urandom.1GB

  How to measure

    Then I performed compression for each block, 4096 bytes, and
    measured total compression time and output size. See attached
    mycompress.c.

  Result

    See attached file result.txt.

  Discussion

    For both kinds of data, lzo's compression was considerably quicker
    than zlib's. Compression ratio is about 37% for urandom data, and
    about 8.5% for zero data. Actual situation of physical memory
    would be in between the two cases, and so I guess average
    compression time ratio is between 37% and 8.5%.

    Although beyond the topic of this patch set, we can estimate worst
    compression time on more data size since compression is performed
    block size wise and the compression time increases
    linearly. Estimated worst time on 2TB memory is about 15 hours for
    lzo and about 40 hours for zlib. In this case, compressed data
    size is larger than the original, so they are really not used,
    compression time is fully meaningless. I think compression must be
    done in parallel, and I'll post such patch later.

Diffstat

  * makedumpfile

 diskdump_mod.h |    3 +-
 makedumpfile.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++------
 makedumpfile.h |   12 +++++++
 3 files changed, 101 insertions(+), 12 deletions(-)

  * crash

 defs.h     |    1 +
 diskdump.c |   20 +++++++++++++++++++-
 diskdump.h |    3 ++-
 3 files changed, 22 insertions(+), 2 deletions(-)

TODO

  * evaluation including I/O time using actual vmcores

Thanks.
HATAYAMA, Daisuke
/*
 * How to build:
 *
 *   $ gcc -lz -llzo2 ./mycompress.c -o mycompress
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <zlib.h>
#include <lzo/lzo1x.h>

enum
{
	BLOCK_SIZE = 4096
};

enum compression
{
	GLIB = 0,
	LZO
};

static inline size_t max(size_t a, size_t b)
{
	return a >= b ? a : b;
}

static inline size_t compressBoundLZO(size_t size)
{
	return size + size / 16 + 64 + 3;
}

static inline double getdtime(void)
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (double)tv.tv_sec + (double)tv.tv_usec * 0.001 * 0.001;
}

static void print_usage(void)
{
	printf("usage: mycompress [glib|lzo] <input file> <output file>\n");
}

int main(int argc, char **argv)
{
	enum compression flag_compress;
	FILE *fi = NULL, *fo = NULL;
	char *bufout = NULL;
	lzo_bytep wrkmem = NULL;
	unsigned long size_out, len_bufout;
	double t_compress_start, t_compress_end, t_compress_total;
	double t_io_start, t_io_end, t_io_total;
	size_t total_input_bytes, total_output_bytes;

	if (argc != 4) {
		print_usage();
		return EXIT_FAILURE;
	}

	if (strncmp(argv[1], "glib", 4) == 0) {
		flag_compress = GLIB;
	}

	else if (strncmp(argv[1], "lzo", 3) == 0) {
		if (lzo_init() != LZO_E_OK) {
			fprintf(stderr, "lzo_init() failed\n");
			return EXIT_FAILURE;
		}
		flag_compress = LZO;
	}

	else {
		return EXIT_FAILURE;
	}

	fi = fopen(argv[2], "r");
	if (!fi) {
		perror("fopen");
		goto error;
	}
	fo = fopen(argv[3], "w");
	if (!fo) {
		perror("fopen");
		goto error;
	}
	switch (flag_compress) {
	case GLIB:
		len_bufout = compressBound(BLOCK_SIZE);

		break;
	case LZO:
		len_bufout = compressBoundLZO(BLOCK_SIZE);
		break;
	}
	bufout = malloc(len_bufout);
	if (!bufout) {
		perror("malloc");
		goto error;
	}
	wrkmem = malloc(LZO1X_1_MEM_COMPRESS);
	if (!wrkmem) {
		perror("malloc");
		goto error;
	}

	t_compress_start = t_compress_end = t_compress_total = 0;
	t_io_start = t_io_end = t_io_total = 0;
	total_input_bytes = total_output_bytes = 0;

	while (!ferror(fi)) {
		char buf[BLOCK_SIZE];
		unsigned long size_out;

		total_input_bytes += BLOCK_SIZE;

		if (fread(buf, sizeof(buf), 1, fi) != 1) {
			if (feof(fi))
				break;
			perror("fread");
			goto error;
		}

		/*
		 * For size_out, GLIB needs output buffer size, while
		 * LZO original data size.
		 */
		switch (flag_compress) {
		case GLIB: size_out = len_bufout; break;
		case LZO: size_out = BLOCK_SIZE; break;
		}

		t_compress_start = getdtime();
		switch (flag_compress) {
		case GLIB:
			if (compress2(bufout, &size_out, buf, BLOCK_SIZE,
				      Z_BEST_SPEED) != Z_OK) {
				fprintf(stderr, "glib compression failed\n");
				goto error;
			}
			break;
		case LZO:
			if (lzo1x_1_compress(buf, BLOCK_SIZE, bufout,
					     &size_out, wrkmem) != LZO_E_OK) {
				fprintf(stderr, "lzo compression failed\n");
				goto error;
			}
			break;
		}

		t_compress_end = getdtime();
		t_compress_total += t_compress_end - t_compress_start;

		t_io_start = getdtime();
		if (fwrite(bufout, size_out, 1, fo) != 1) {
			perror("fwrite");
			goto error;
		}
		t_io_end = getdtime();
		t_io_total += t_io_end - t_io_start;

		total_output_bytes += size_out;
	}

	printf("Input size: %d bytes\n", total_input_bytes);
	printf("Compression Time: %lf seconds\n", t_compress_total);
	printf("Output size: %d bytes\n", total_output_bytes);
	printf("IO Time: %lf seconds\n", t_io_total);

error:
	if (fi)
		fclose(fi);
	if (fo)
		fclose(fo);
	free(wrkmem);
	return 0;
}
  * /dev/urandom
				lzo		zlib		compression time ratio(%)
     10MBytes
compression time(sec)		0.271553	0.721236	37.65106012
output size(bytes)		10537086	10513920	
compression size ratio(%)	100.4502445	100.2294026	

     100MBytes
compression time(sec)		2.671278	7.229928	36.94750487
output size(bytes)		105370774	105139200	
compression size ratio(%)	100.4854756	100.2646381	

     1GBytes
compression time(sec)		27.627126	74.94164	36.86485377
output size(bytes)		1078997064	1076625408	
compression size ratio(%)	100.489049	100.2681722	

  * /dev/zero
				lzo		zlib		compression time ratio(%)
     10MBytes
compression time(sec)		0.020834	0.238794	8.724674824
output size(bytes)		71680		104960		
compression size ratio(%)	0.683326825	1.000585709	

     100MBytes
compression time(sec)		0.208346	2.441701	8.532821996
output size(bytes)		716800		1049600		
compression size ratio(%)	0.683567048	1.000937463	

     1GBytes
compression time(sec)		2.123407	26.047801	8.151962617
output size(bytes)		7340032		10747904	
compression size ratio(%)	0.683591142	1.000972744

Attachment: 0001-Add-LZO-Support.patch
Description: Binary data

Attachment: 0001-Support-LZO-compression-format.patch
Description: Binary data

Attachment: 0002-Add-Compression-and-IO-time-report.patch
Description: Binary data

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux