summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-03-06 15:57:38 -0800
committerKees Cook <keescook@chromium.org>2018-03-07 12:43:35 -0800
commitfe1d475888eecf1319458ee916e642e3e5e41c28 (patch)
treed975fba8225eec25ad2b3fd9ba5fd8e7ccfeb3dd
parent555974068ee533e8e0c6093ec7ca1682057aa4c1 (diff)
pstore: Select compression at runtime
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>
-rw-r--r--fs/pstore/Kconfig96
-rw-r--r--fs/pstore/inode.c2
-rw-r--r--fs/pstore/internal.h3
-rw-r--r--fs/pstore/platform.c134
4 files changed, 151 insertions, 84 deletions
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index 898abafea7a5..e4e22026c7a1 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -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
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index d814723fb27d..5fcb845b9fec 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -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)
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index c029314478fa..fb767e28aeb2 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -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
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index df54dd87598a..06e3b280c3a5 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -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");