pstore: Select compression at runtime
authorKees Cook <keescook@chromium.org>
Tue, 6 Mar 2018 23:57:38 +0000 (15:57 -0800)
committerKees Cook <keescook@chromium.org>
Wed, 7 Mar 2018 20:43:35 +0000 (12:43 -0800)
To allow for easier build test coverage and run-time testing, this allows
multiple compression algorithms to be built into pstore. Still only one
is supported to operate at a time (which can be selected at build time
or at boot time, similar to how LSMs are selected).

Signed-off-by: Kees Cook <keescook@chromium.org>
fs/pstore/Kconfig
fs/pstore/inode.c
fs/pstore/internal.h
fs/pstore/platform.c

index 898abafea7a572043da172367d71057328dc879b..e4e22026c7a1dd81598d1c8e6c782814d260150f 100644 (file)
@@ -12,55 +12,93 @@ config PSTORE
           If you don't have a platform persistent store driver,
           say N.
 
-choice
-        prompt "Choose compression algorithm"
-        depends on PSTORE
-        default PSTORE_ZLIB_COMPRESS
-        help
-          This option chooses compression algorithm.
-
-         Currently, pstore has support for 5 compression algorithms:
-         zlib, lzo, lz4, lz4hc and 842.
-
-         The default compression algorithm is zlib.
-
 config PSTORE_ZLIB_COMPRESS
-        bool "ZLIB"
-        select ZLIB_DEFLATE
-        select ZLIB_INFLATE
-        help
-          This option enables ZLIB compression algorithm support.
+       bool "ZLIB compression"
+       default y
+       depends on PSTORE
+       select ZLIB_DEFLATE
+       select ZLIB_INFLATE
+       help
+         This option enables ZLIB compression algorithm support.
 
 config PSTORE_LZO_COMPRESS
-        bool "LZO"
-        select LZO_COMPRESS
-        select LZO_DECOMPRESS
-        help
-          This option enables LZO compression algorithm support.
+       bool "LZO compression"
+       depends on PSTORE
+       select LZO_COMPRESS
+       select LZO_DECOMPRESS
+       help
+         This option enables LZO compression algorithm support.
 
 config PSTORE_LZ4_COMPRESS
-        bool "LZ4"
-        select LZ4_COMPRESS
-        select LZ4_DECOMPRESS
-        help
-          This option enables LZ4 compression algorithm support.
+       bool "LZ4 compression"
+       depends on PSTORE
+       select LZ4_COMPRESS
+       select LZ4_DECOMPRESS
+       help
+         This option enables LZ4 compression algorithm support.
 
 config PSTORE_LZ4HC_COMPRESS
-       bool "LZ4HC"
+       bool "LZ4HC compression"
+       depends on PSTORE
        select LZ4HC_COMPRESS
        select LZ4_DECOMPRESS
        help
          This option enables LZ4HC (high compression) mode algorithm.
 
 config PSTORE_842_COMPRESS
-       bool "842"
+       bool "842 compression"
+       depends on PSTORE
        select 842_COMPRESS
        select 842_DECOMPRESS
        help
          This option enables 842 compression algorithm support.
 
+config PSTORE_COMPRESS
+       def_bool y
+       depends on PSTORE
+       depends on PSTORE_ZLIB_COMPRESS || PSTORE_LZO_COMPRESS ||       \
+                  PSTORE_LZ4_COMPRESS || PSTORE_LZ4HC_COMPRESS ||      \
+                  PSTORE_842_COMPRESS
+
+choice
+       prompt "Default pstore compression algorithm"
+       depends on PSTORE_COMPRESS
+       help
+         This option chooses the default active compression algorithm.
+         This change be changed at boot with "pstore.compress=..." on
+         the kernel command line.
+
+         Currently, pstore has support for 5 compression algorithms:
+         zlib, lzo, lz4, lz4hc and 842.
+
+         The default compression algorithm is zlib.
+
+       config PSTORE_ZLIB_COMPRESS_DEFAULT
+               bool "zlib" if PSTORE_ZLIB_COMPRESS=y
+
+       config PSTORE_LZO_COMPRESS_DEFAULT
+               bool "lzo" if PSTORE_LZO_COMPRESS=y
+
+       config PSTORE_LZ4_COMPRESS_DEFAULT
+               bool "lz4" if PSTORE_LZ4_COMPRESS=y
+
+       config PSTORE_LZ4HC_COMPRESS_DEFAULT
+               bool "lz4hc" if PSTORE_LZ4HC_COMPRESS=y
+
+       config PSTORE_842_COMPRESS_DEFAULT
+               bool "842" if PSTORE_842_COMPRESS=y
+
 endchoice
 
+config PSTORE_COMPRESS_DEFAULT
+       string
+       depends on PSTORE_COMPRESS
+       default "zlib" if PSTORE_ZLIB_COMPRESS_DEFAULT
+       default "lzo" if PSTORE_LZO_COMPRESS_DEFAULT
+       default "lz4" if PSTORE_LZ4_COMPRESS_DEFAULT
+       default "lz4hc" if PSTORE_LZ4HC_COMPRESS_DEFAULT
+       default "842" if PSTORE_842_COMPRESS_DEFAULT
+
 config PSTORE_CONSOLE
        bool "Log kernel console messages"
        depends on PSTORE
index d814723fb27dcdfc80168bf97a5c10ab20fcc0c2..5fcb845b9fec1295c1a3a894acf8c2ce042d3f17 100644 (file)
@@ -486,6 +486,8 @@ static int __init init_pstore_fs(void)
 {
        int err;
 
+       pstore_choose_compression();
+
        /* Create a convenient mount point for people to access pstore */
        err = sysfs_create_mount_point(fs_kobj, "pstore");
        if (err)
index c029314478fad020a46e27562ee5936d0e3b407b..fb767e28aeb28333ffbc2446b94ad5167234e3ba 100644 (file)
@@ -37,4 +37,7 @@ extern bool   pstore_is_mounted(void);
 extern void    pstore_record_init(struct pstore_record *record,
                                   struct pstore_info *psi);
 
+/* Called during module_init() */
+extern void __init pstore_choose_compression(void);
+
 #endif
index df54dd87598a24588cdeadafa01be33049a0dc32..06e3b280c3a5b4be4fd8e3998a53dca0213536ad 100644 (file)
@@ -77,6 +77,12 @@ static DEFINE_SPINLOCK(pstore_lock);
 struct pstore_info *psinfo;
 
 static char *backend;
+static char *compress =
+#ifdef CONFIG_PSTORE_COMPRESS_DEFAULT
+               CONFIG_PSTORE_COMPRESS_DEFAULT;
+#else
+               NULL;
+#endif
 
 /* Compression parameters */
 #ifdef CONFIG_PSTORE_ZLIB_COMPRESS
@@ -84,7 +90,11 @@ static char *backend;
 #define WINDOW_BITS 12
 #define MEM_LEVEL 4
 static struct z_stream_s stream;
-#else
+#endif
+#if defined(CONFIG_PSTORE_LZO_COMPRESS)   || \
+    defined(CONFIG_PSTORE_LZ4_COMPRESS)   || \
+    defined(CONFIG_PSTORE_LZ4HC_COMPRESS) || \
+    defined(CONFIG_PSTORE_842_COMPRESS)
 static unsigned char *workspace;
 #endif
 
@@ -268,14 +278,6 @@ static void free_zlib(void)
        big_oops_buf = NULL;
        big_oops_buf_sz = 0;
 }
-
-static const struct pstore_zbackend backend_zlib = {
-       .compress       = compress_zlib,
-       .decompress     = decompress_zlib,
-       .allocate       = allocate_zlib,
-       .free           = free_zlib,
-       .name           = "zlib",
-};
 #endif
 
 #ifdef CONFIG_PSTORE_LZO_COMPRESS
@@ -329,14 +331,6 @@ static void free_lzo(void)
        big_oops_buf = NULL;
        big_oops_buf_sz = 0;
 }
-
-static const struct pstore_zbackend backend_lzo = {
-       .compress       = compress_lzo,
-       .decompress     = decompress_lzo,
-       .allocate       = allocate_lzo,
-       .free           = free_lzo,
-       .name           = "lzo",
-};
 #endif
 
 #if defined(CONFIG_PSTORE_LZ4_COMPRESS) || defined(CONFIG_PSTORE_LZ4HC_COMPRESS)
@@ -396,14 +390,6 @@ static void allocate_lz4(void)
                workspace = NULL;
        }
 }
-
-static const struct pstore_zbackend backend_lz4 = {
-       .compress       = compress_lz4,
-       .decompress     = decompress_lz4,
-       .allocate       = allocate_lz4,
-       .free           = free_lz4,
-       .name           = "lz4",
-};
 #endif
 
 #ifdef CONFIG_PSTORE_LZ4HC_COMPRESS
@@ -438,14 +424,6 @@ static void allocate_lz4hc(void)
                workspace = NULL;
        }
 }
-
-static const struct pstore_zbackend backend_lz4hc = {
-       .compress       = compress_lz4hc,
-       .decompress     = decompress_lz4,
-       .allocate       = allocate_lz4hc,
-       .free           = free_lz4,
-       .name           = "lz4hc",
-};
 #endif
 
 #ifdef CONFIG_PSTORE_842_COMPRESS
@@ -508,30 +486,58 @@ static void free_842(void)
        big_oops_buf = NULL;
        big_oops_buf_sz = 0;
 }
-
-static const struct pstore_zbackend backend_842 = {
-       .compress       = compress_842,
-       .decompress     = decompress_842,
-       .allocate       = allocate_842,
-       .free           = free_842,
-       .name           = "842",
-};
 #endif
 
-static const struct pstore_zbackend *zbackend =
-#if defined(CONFIG_PSTORE_ZLIB_COMPRESS)
-       &backend_zlib;
-#elif defined(CONFIG_PSTORE_LZO_COMPRESS)
-       &backend_lzo;
-#elif defined(CONFIG_PSTORE_LZ4_COMPRESS)
-       &backend_lz4;
-#elif defined(CONFIG_PSTORE_LZ4HC_COMPRESS)
-       &backend_lz4hc;
-#elif defined(CONFIG_PSTORE_842_COMPRESS)
-       &backend_842;
-#else
-       NULL;
+static const struct pstore_zbackend *zbackend __ro_after_init;
+
+static const struct pstore_zbackend zbackends[] = {
+#ifdef CONFIG_PSTORE_ZLIB_COMPRESS
+       {
+               .compress       = compress_zlib,
+               .decompress     = decompress_zlib,
+               .allocate       = allocate_zlib,
+               .free           = free_zlib,
+               .name           = "zlib",
+       },
+#endif
+#ifdef CONFIG_PSTORE_LZO_COMPRESS
+       {
+               .compress       = compress_lzo,
+               .decompress     = decompress_lzo,
+               .allocate       = allocate_lzo,
+               .free           = free_lzo,
+               .name           = "lzo",
+       },
+#endif
+#ifdef CONFIG_PSTORE_LZ4_COMPRESS
+       {
+               .compress       = compress_lz4,
+               .decompress     = decompress_lz4,
+               .allocate       = allocate_lz4,
+               .free           = free_lz4,
+               .name           = "lz4",
+       },
+#endif
+#ifdef CONFIG_PSTORE_LZ4HC_COMPRESS
+       {
+               .compress       = compress_lz4hc,
+               .decompress     = decompress_lz4,
+               .allocate       = allocate_lz4hc,
+               .free           = free_lz4,
+               .name           = "lz4hc",
+       },
 #endif
+#ifdef CONFIG_PSTORE_842_COMPRESS
+       {
+               .compress       = compress_842,
+               .decompress     = decompress_842,
+               .allocate       = allocate_842,
+               .free           = free_842,
+               .name           = "842",
+       },
+#endif
+       { }
+};
 
 static int pstore_compress(const void *in, void *out,
                           size_t inlen, size_t outlen)
@@ -553,7 +559,6 @@ static int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen)
 static void allocate_buf_for_compression(void)
 {
        if (zbackend) {
-               pr_info("using %s compression\n", zbackend->name);
                zbackend->allocate();
        } else {
                pr_err("allocate compression buffer error!\n");
@@ -1022,5 +1027,24 @@ static void pstore_timefunc(struct timer_list *unused)
                          jiffies + msecs_to_jiffies(pstore_update_ms));
 }
 
+void __init pstore_choose_compression(void)
+{
+       const struct pstore_zbackend *step;
+
+       if (!compress)
+               return;
+
+       for (step = zbackends; step->name; step++) {
+               if (!strcmp(compress, step->name)) {
+                       zbackend = step;
+                       pr_info("using %s compression\n", zbackend->name);
+                       return;
+               }
+       }
+}
+
+module_param(compress, charp, 0444);
+MODULE_PARM_DESC(compress, "Pstore compression to use");
+
 module_param(backend, charp, 0444);
 MODULE_PARM_DESC(backend, "Pstore backend to use");