chiark / gitweb /
coredump: make compression configurable
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 26 Jun 2014 00:53:40 +0000 (20:53 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 26 Jun 2014 05:41:04 +0000 (01:41 -0400)
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.

src/journal/compress.c
src/journal/compress.h
src/journal/coredump.c
src/journal/test-compress.c

index f36c4308017283540aeecc0a87416efa198ca9b3..1fc62ead2a9b68ca9c4489d840d66a8dff7c0406 100644 (file)
@@ -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;
index f37a6b3d148e59efae4da213f3b06e883223fec4..f25fe86abd56423c175bdd7832e9ac2583fd03c1 100644 (file)
@@ -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);
index 1c5c99c39d8975cbed201cf576802d14d5520e6b..afd69cda5d88f0e087fc6ed3e5223caac4fdca97 100644 (file)
 #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) {
index b098ef93a850c02bb5c3a5a7c8e42a40874c82c9..0806145d4bdc352dd2a44c8b618ea44b7f023ffc 100644 (file)
@@ -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);