diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2014-06-25 20:53:40 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2014-06-26 01:41:04 -0400 |
commit | 347272731e15d3c4a70fad7ccd7185e8e8059d01 (patch) | |
tree | 11c1d96506fab4ed3240a4f432763e774fd03f6e /src | |
parent | cfd652ed617282b06ccbdedb7adc6963b901dde7 (diff) |
coredump: make compression configurable
Add Compression={none,xz} and CompressionLevel=0-9 settings. Defaults
are xz/6.
Compression=filesystem may be added later.
I picked "xz" for the compression "type", since we might want to add
different compressors later on. XZ is fairly memory and CPU intensive, and
embedded users will likely want to use LZO or some other lightweight compression
mechanism.
Diffstat (limited to 'src')
-rw-r--r-- | src/journal/compress.c | 4 | ||||
-rw-r--r-- | src/journal/compress.h | 2 | ||||
-rw-r--r-- | src/journal/coredump.c | 73 | ||||
-rw-r--r-- | src/journal/test-compress.c | 2 |
4 files changed, 62 insertions, 19 deletions
diff --git a/src/journal/compress.c b/src/journal/compress.c index f36c430801..1fc62ead2a 100644 --- a/src/journal/compress.c +++ b/src/journal/compress.c @@ -203,7 +203,7 @@ fail: return b; } -int compress_stream(int fdf, int fdt, off_t max_bytes) { +int compress_stream(int fdf, int fdt, uint32_t preset, off_t max_bytes) { _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT; lzma_ret ret; @@ -213,7 +213,7 @@ int compress_stream(int fdf, int fdt, off_t max_bytes) { assert(fdf >= 0); assert(fdt >= 0); - ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64); + ret = lzma_easy_encoder(&s, preset, LZMA_CHECK_CRC64); if (ret != LZMA_OK) { log_error("Failed to initialize XZ encoder: code %d", ret); return -EINVAL; diff --git a/src/journal/compress.h b/src/journal/compress.h index f37a6b3d14..f25fe86abd 100644 --- a/src/journal/compress.h +++ b/src/journal/compress.h @@ -35,5 +35,5 @@ bool uncompress_startswith(const void *src, uint64_t src_size, const void *prefix, uint64_t prefix_len, uint8_t extra); -int compress_stream(int fdf, int fdt, off_t max_size); +int compress_stream(int fdf, int fdt, uint32_t preset, off_t max_size); int decompress_stream(int fdf, int fdt, off_t max_size); diff --git a/src/journal/coredump.c b/src/journal/coredump.c index 1c5c99c39d..afd69cda5d 100644 --- a/src/journal/coredump.c +++ b/src/journal/coredump.c @@ -44,8 +44,14 @@ #include "compress.h" #ifdef HAVE_ACL -#include <sys/acl.h> -#include "acl-util.h" +# include <sys/acl.h> +# include "acl-util.h" +#endif + +#ifdef HAVE_XZ +# include <lzma.h> +#else +# define LZMA_PRESET_DEFAULT 0 #endif /* The maximum size up to which we process coredumps */ @@ -83,11 +89,6 @@ typedef enum CoredumpStorage { _COREDUMP_STORAGE_INVALID = -1 } CoredumpStorage; -static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL; -static off_t arg_process_size_max = PROCESS_SIZE_MAX; -static off_t arg_external_size_max = EXTERNAL_SIZE_MAX; -static size_t arg_journal_size_max = JOURNAL_SIZE_MAX; - static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = { [COREDUMP_STORAGE_NONE] = "none", [COREDUMP_STORAGE_EXTERNAL] = "external", @@ -96,15 +97,45 @@ static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = { }; DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage); -static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_storage, coredump_storage, CoredumpStorage, "Failed to parse storage setting"); +static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_storage, coredump_storage, + CoredumpStorage, + "Failed to parse storage setting"); + +typedef enum CoredumpCompression { + COREDUMP_COMPRESSION_NONE, + COREDUMP_COMPRESSION_XZ, + _COREDUMP_COMPRESSION_MAX, + _COREDUMP_COMPRESSION_INVALID = -1 +} CoredumpCompression; + +static const char* const coredump_compression_table[_COREDUMP_COMPRESSION_MAX] = { + [COREDUMP_COMPRESSION_NONE] = "none", + [COREDUMP_COMPRESSION_XZ] = "xz", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_compression, CoredumpCompression); +static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_compression, coredump_compression, + CoredumpCompression, + "Failed to parse compression setting"); + +static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL; +static CoredumpCompression arg_compression = COREDUMP_COMPRESSION_XZ; +static unsigned arg_compression_level = LZMA_PRESET_DEFAULT; + +static off_t arg_process_size_max = PROCESS_SIZE_MAX; +static off_t arg_external_size_max = EXTERNAL_SIZE_MAX; +static size_t arg_journal_size_max = JOURNAL_SIZE_MAX; static int parse_config(void) { static const ConfigTableItem items[] = { - { "Coredump", "ProcessSizeMax", config_parse_iec_off, 0, &arg_process_size_max }, - { "Coredump", "ExternalSizeMax", config_parse_iec_off, 0, &arg_external_size_max }, - { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, - { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, + { "Coredump", "Storage", config_parse_coredump_storage, 0, &arg_storage }, + { "Coredump", "Compression", config_parse_coredump_compression, 0, &arg_compression }, + { "Coredump", "CompressionLevel", config_parse_unsigned, 0, &arg_compression_level }, + + { "Coredump", "ProcessSizeMax", config_parse_iec_off, 0, &arg_process_size_max }, + { "Coredump", "ExternalSizeMax", config_parse_iec_off, 0, &arg_external_size_max }, + { "Coredump", "JournalSizeMax", config_parse_iec_size, 0, &arg_journal_size_max }, {} }; @@ -118,6 +149,13 @@ static int parse_config(void) { false, false, NULL); + +#ifdef HAVE_XZ + if (arg_compression_level > 9) { + log_warning("Invalid CompressionLevel %u, ignoring.", arg_compression_level); + arg_compression_level = LZMA_PRESET_DEFAULT; + } +#endif } static int fix_acl(int fd, uid_t uid) { @@ -319,7 +357,8 @@ static int save_external_coredump(const char *info[_INFO_LEN], #ifdef HAVE_XZ /* If we will remove the coredump anyway, do not compress. */ - if (maybe_remove_external_coredump(NULL, st.st_size) == 0) { + if (maybe_remove_external_coredump(NULL, st.st_size) == 0 + && arg_compression == COREDUMP_COMPRESSION_XZ) { _cleanup_free_ char *fn2 = NULL; char *tmp2; @@ -332,7 +371,7 @@ static int save_external_coredump(const char *info[_INFO_LEN], goto uncompressed; } - r = compress_stream(fd, fd2, -1); + r = compress_stream(fd, fd2, arg_compression_level, -1); if (r < 0) { log_error("Failed to compress %s: %s", tmp2, strerror(-r)); unlink_noerrno(tmp2); @@ -458,7 +497,11 @@ int main(int argc, char* argv[]) { /* Ignore all parse errors */ parse_config(); - log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage)); + log_debug("Selected storage '%s'.", + coredump_storage_to_string(arg_storage)); + log_debug("Selected compression %s:%u.", + coredump_compression_to_string(arg_storage), + arg_compression_level); r = parse_uid(argv[INFO_UID + 1], &uid); if (r < 0) { diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c index b098ef93a8..0806145d4b 100644 --- a/src/journal/test-compress.c +++ b/src/journal/test-compress.c @@ -84,7 +84,7 @@ static void test_compress_stream(const char *srcfile) { assert_se((dst = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC)) >= 0); - r = compress_stream(src, dst, -1); + r = compress_stream(src, dst, 1, -1); assert(r == 0); assert_se(asprintf(&cmd, "xzcat %s | diff %s -", pattern, srcfile) > 0); |