diff options
author | Kees Cook <keescook@chromium.org> | 2018-03-06 18:57:38 -0500 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2018-03-07 15:43:35 -0500 |
commit | fe1d475888eecf1319458ee916e642e3e5e41c28 (patch) | |
tree | d975fba8225eec25ad2b3fd9ba5fd8e7ccfeb3dd | |
parent | 555974068ee533e8e0c6093ec7ca1682057aa4c1 (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/Kconfig | 96 | ||||
-rw-r--r-- | fs/pstore/inode.c | 2 | ||||
-rw-r--r-- | fs/pstore/internal.h | 3 | ||||
-rw-r--r-- | fs/pstore/platform.c | 134 |
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 | |||
12 | If you don't have a platform persistent store driver, | 12 | If you don't have a platform persistent store driver, |
13 | say N. | 13 | say N. |
14 | 14 | ||
15 | choice | ||
16 | prompt "Choose compression algorithm" | ||
17 | depends on PSTORE | ||
18 | default PSTORE_ZLIB_COMPRESS | ||
19 | help | ||
20 | This option chooses compression algorithm. | ||
21 | |||
22 | Currently, pstore has support for 5 compression algorithms: | ||
23 | zlib, lzo, lz4, lz4hc and 842. | ||
24 | |||
25 | The default compression algorithm is zlib. | ||
26 | |||
27 | config PSTORE_ZLIB_COMPRESS | 15 | config PSTORE_ZLIB_COMPRESS |
28 | bool "ZLIB" | 16 | bool "ZLIB compression" |
29 | select ZLIB_DEFLATE | 17 | default y |
30 | select ZLIB_INFLATE | 18 | depends on PSTORE |
31 | help | 19 | select ZLIB_DEFLATE |
32 | This option enables ZLIB compression algorithm support. | 20 | select ZLIB_INFLATE |
21 | help | ||
22 | This option enables ZLIB compression algorithm support. | ||
33 | 23 | ||
34 | config PSTORE_LZO_COMPRESS | 24 | config PSTORE_LZO_COMPRESS |
35 | bool "LZO" | 25 | bool "LZO compression" |
36 | select LZO_COMPRESS | 26 | depends on PSTORE |
37 | select LZO_DECOMPRESS | 27 | select LZO_COMPRESS |
38 | help | 28 | select LZO_DECOMPRESS |
39 | This option enables LZO compression algorithm support. | 29 | help |
30 | This option enables LZO compression algorithm support. | ||
40 | 31 | ||
41 | config PSTORE_LZ4_COMPRESS | 32 | config PSTORE_LZ4_COMPRESS |
42 | bool "LZ4" | 33 | bool "LZ4 compression" |
43 | select LZ4_COMPRESS | 34 | depends on PSTORE |
44 | select LZ4_DECOMPRESS | 35 | select LZ4_COMPRESS |
45 | help | 36 | select LZ4_DECOMPRESS |
46 | This option enables LZ4 compression algorithm support. | 37 | help |
38 | This option enables LZ4 compression algorithm support. | ||
47 | 39 | ||
48 | config PSTORE_LZ4HC_COMPRESS | 40 | config PSTORE_LZ4HC_COMPRESS |
49 | bool "LZ4HC" | 41 | bool "LZ4HC compression" |
42 | depends on PSTORE | ||
50 | select LZ4HC_COMPRESS | 43 | select LZ4HC_COMPRESS |
51 | select LZ4_DECOMPRESS | 44 | select LZ4_DECOMPRESS |
52 | help | 45 | help |
53 | This option enables LZ4HC (high compression) mode algorithm. | 46 | This option enables LZ4HC (high compression) mode algorithm. |
54 | 47 | ||
55 | config PSTORE_842_COMPRESS | 48 | config PSTORE_842_COMPRESS |
56 | bool "842" | 49 | bool "842 compression" |
50 | depends on PSTORE | ||
57 | select 842_COMPRESS | 51 | select 842_COMPRESS |
58 | select 842_DECOMPRESS | 52 | select 842_DECOMPRESS |
59 | help | 53 | help |
60 | This option enables 842 compression algorithm support. | 54 | This option enables 842 compression algorithm support. |
61 | 55 | ||
56 | config PSTORE_COMPRESS | ||
57 | def_bool y | ||
58 | depends on PSTORE | ||
59 | depends on PSTORE_ZLIB_COMPRESS || PSTORE_LZO_COMPRESS || \ | ||
60 | PSTORE_LZ4_COMPRESS || PSTORE_LZ4HC_COMPRESS || \ | ||
61 | PSTORE_842_COMPRESS | ||
62 | |||
63 | choice | ||
64 | prompt "Default pstore compression algorithm" | ||
65 | depends on PSTORE_COMPRESS | ||
66 | help | ||
67 | This option chooses the default active compression algorithm. | ||
68 | This change be changed at boot with "pstore.compress=..." on | ||
69 | the kernel command line. | ||
70 | |||
71 | Currently, pstore has support for 5 compression algorithms: | ||
72 | zlib, lzo, lz4, lz4hc and 842. | ||
73 | |||
74 | The default compression algorithm is zlib. | ||
75 | |||
76 | config PSTORE_ZLIB_COMPRESS_DEFAULT | ||
77 | bool "zlib" if PSTORE_ZLIB_COMPRESS=y | ||
78 | |||
79 | config PSTORE_LZO_COMPRESS_DEFAULT | ||
80 | bool "lzo" if PSTORE_LZO_COMPRESS=y | ||
81 | |||
82 | config PSTORE_LZ4_COMPRESS_DEFAULT | ||
83 | bool "lz4" if PSTORE_LZ4_COMPRESS=y | ||
84 | |||
85 | config PSTORE_LZ4HC_COMPRESS_DEFAULT | ||
86 | bool "lz4hc" if PSTORE_LZ4HC_COMPRESS=y | ||
87 | |||
88 | config PSTORE_842_COMPRESS_DEFAULT | ||
89 | bool "842" if PSTORE_842_COMPRESS=y | ||
90 | |||
62 | endchoice | 91 | endchoice |
63 | 92 | ||
93 | config PSTORE_COMPRESS_DEFAULT | ||
94 | string | ||
95 | depends on PSTORE_COMPRESS | ||
96 | default "zlib" if PSTORE_ZLIB_COMPRESS_DEFAULT | ||
97 | default "lzo" if PSTORE_LZO_COMPRESS_DEFAULT | ||
98 | default "lz4" if PSTORE_LZ4_COMPRESS_DEFAULT | ||
99 | default "lz4hc" if PSTORE_LZ4HC_COMPRESS_DEFAULT | ||
100 | default "842" if PSTORE_842_COMPRESS_DEFAULT | ||
101 | |||
64 | config PSTORE_CONSOLE | 102 | config PSTORE_CONSOLE |
65 | bool "Log kernel console messages" | 103 | bool "Log kernel console messages" |
66 | depends on PSTORE | 104 | 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) | |||
486 | { | 486 | { |
487 | int err; | 487 | int err; |
488 | 488 | ||
489 | pstore_choose_compression(); | ||
490 | |||
489 | /* Create a convenient mount point for people to access pstore */ | 491 | /* Create a convenient mount point for people to access pstore */ |
490 | err = sysfs_create_mount_point(fs_kobj, "pstore"); | 492 | err = sysfs_create_mount_point(fs_kobj, "pstore"); |
491 | if (err) | 493 | 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); | |||
37 | extern void pstore_record_init(struct pstore_record *record, | 37 | extern void pstore_record_init(struct pstore_record *record, |
38 | struct pstore_info *psi); | 38 | struct pstore_info *psi); |
39 | 39 | ||
40 | /* Called during module_init() */ | ||
41 | extern void __init pstore_choose_compression(void); | ||
42 | |||
40 | #endif | 43 | #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); | |||
77 | struct pstore_info *psinfo; | 77 | struct pstore_info *psinfo; |
78 | 78 | ||
79 | static char *backend; | 79 | static char *backend; |
80 | static char *compress = | ||
81 | #ifdef CONFIG_PSTORE_COMPRESS_DEFAULT | ||
82 | CONFIG_PSTORE_COMPRESS_DEFAULT; | ||
83 | #else | ||
84 | NULL; | ||
85 | #endif | ||
80 | 86 | ||
81 | /* Compression parameters */ | 87 | /* Compression parameters */ |
82 | #ifdef CONFIG_PSTORE_ZLIB_COMPRESS | 88 | #ifdef CONFIG_PSTORE_ZLIB_COMPRESS |
@@ -84,7 +90,11 @@ static char *backend; | |||
84 | #define WINDOW_BITS 12 | 90 | #define WINDOW_BITS 12 |
85 | #define MEM_LEVEL 4 | 91 | #define MEM_LEVEL 4 |
86 | static struct z_stream_s stream; | 92 | static struct z_stream_s stream; |
87 | #else | 93 | #endif |
94 | #if defined(CONFIG_PSTORE_LZO_COMPRESS) || \ | ||
95 | defined(CONFIG_PSTORE_LZ4_COMPRESS) || \ | ||
96 | defined(CONFIG_PSTORE_LZ4HC_COMPRESS) || \ | ||
97 | defined(CONFIG_PSTORE_842_COMPRESS) | ||
88 | static unsigned char *workspace; | 98 | static unsigned char *workspace; |
89 | #endif | 99 | #endif |
90 | 100 | ||
@@ -268,14 +278,6 @@ static void free_zlib(void) | |||
268 | big_oops_buf = NULL; | 278 | big_oops_buf = NULL; |
269 | big_oops_buf_sz = 0; | 279 | big_oops_buf_sz = 0; |
270 | } | 280 | } |
271 | |||
272 | static const struct pstore_zbackend backend_zlib = { | ||
273 | .compress = compress_zlib, | ||
274 | .decompress = decompress_zlib, | ||
275 | .allocate = allocate_zlib, | ||
276 | .free = free_zlib, | ||
277 | .name = "zlib", | ||
278 | }; | ||
279 | #endif | 281 | #endif |
280 | 282 | ||
281 | #ifdef CONFIG_PSTORE_LZO_COMPRESS | 283 | #ifdef CONFIG_PSTORE_LZO_COMPRESS |
@@ -329,14 +331,6 @@ static void free_lzo(void) | |||
329 | big_oops_buf = NULL; | 331 | big_oops_buf = NULL; |
330 | big_oops_buf_sz = 0; | 332 | big_oops_buf_sz = 0; |
331 | } | 333 | } |
332 | |||
333 | static const struct pstore_zbackend backend_lzo = { | ||
334 | .compress = compress_lzo, | ||
335 | .decompress = decompress_lzo, | ||
336 | .allocate = allocate_lzo, | ||
337 | .free = free_lzo, | ||
338 | .name = "lzo", | ||
339 | }; | ||
340 | #endif | 334 | #endif |
341 | 335 | ||
342 | #if defined(CONFIG_PSTORE_LZ4_COMPRESS) || defined(CONFIG_PSTORE_LZ4HC_COMPRESS) | 336 | #if defined(CONFIG_PSTORE_LZ4_COMPRESS) || defined(CONFIG_PSTORE_LZ4HC_COMPRESS) |
@@ -396,14 +390,6 @@ static void allocate_lz4(void) | |||
396 | workspace = NULL; | 390 | workspace = NULL; |
397 | } | 391 | } |
398 | } | 392 | } |
399 | |||
400 | static const struct pstore_zbackend backend_lz4 = { | ||
401 | .compress = compress_lz4, | ||
402 | .decompress = decompress_lz4, | ||
403 | .allocate = allocate_lz4, | ||
404 | .free = free_lz4, | ||
405 | .name = "lz4", | ||
406 | }; | ||
407 | #endif | 393 | #endif |
408 | 394 | ||
409 | #ifdef CONFIG_PSTORE_LZ4HC_COMPRESS | 395 | #ifdef CONFIG_PSTORE_LZ4HC_COMPRESS |
@@ -438,14 +424,6 @@ static void allocate_lz4hc(void) | |||
438 | workspace = NULL; | 424 | workspace = NULL; |
439 | } | 425 | } |
440 | } | 426 | } |
441 | |||
442 | static const struct pstore_zbackend backend_lz4hc = { | ||
443 | .compress = compress_lz4hc, | ||
444 | .decompress = decompress_lz4, | ||
445 | .allocate = allocate_lz4hc, | ||
446 | .free = free_lz4, | ||
447 | .name = "lz4hc", | ||
448 | }; | ||
449 | #endif | 427 | #endif |
450 | 428 | ||
451 | #ifdef CONFIG_PSTORE_842_COMPRESS | 429 | #ifdef CONFIG_PSTORE_842_COMPRESS |
@@ -508,30 +486,58 @@ static void free_842(void) | |||
508 | big_oops_buf = NULL; | 486 | big_oops_buf = NULL; |
509 | big_oops_buf_sz = 0; | 487 | big_oops_buf_sz = 0; |
510 | } | 488 | } |
511 | |||
512 | static const struct pstore_zbackend backend_842 = { | ||
513 | .compress = compress_842, | ||
514 | .decompress = decompress_842, | ||
515 | .allocate = allocate_842, | ||
516 | .free = free_842, | ||
517 | .name = "842", | ||
518 | }; | ||
519 | #endif | 489 | #endif |
520 | 490 | ||
521 | static const struct pstore_zbackend *zbackend = | 491 | static const struct pstore_zbackend *zbackend __ro_after_init; |
522 | #if defined(CONFIG_PSTORE_ZLIB_COMPRESS) | 492 | |
523 | &backend_zlib; | 493 | static const struct pstore_zbackend zbackends[] = { |
524 | #elif defined(CONFIG_PSTORE_LZO_COMPRESS) | 494 | #ifdef CONFIG_PSTORE_ZLIB_COMPRESS |
525 | &backend_lzo; | 495 | { |
526 | #elif defined(CONFIG_PSTORE_LZ4_COMPRESS) | 496 | .compress = compress_zlib, |
527 | &backend_lz4; | 497 | .decompress = decompress_zlib, |
528 | #elif defined(CONFIG_PSTORE_LZ4HC_COMPRESS) | 498 | .allocate = allocate_zlib, |
529 | &backend_lz4hc; | 499 | .free = free_zlib, |
530 | #elif defined(CONFIG_PSTORE_842_COMPRESS) | 500 | .name = "zlib", |
531 | &backend_842; | 501 | }, |
532 | #else | 502 | #endif |
533 | NULL; | 503 | #ifdef CONFIG_PSTORE_LZO_COMPRESS |
504 | { | ||
505 | .compress = compress_lzo, | ||
506 | .decompress = decompress_lzo, | ||
507 | .allocate = allocate_lzo, | ||
508 | .free = free_lzo, | ||
509 | .name = "lzo", | ||
510 | }, | ||
511 | #endif | ||
512 | #ifdef CONFIG_PSTORE_LZ4_COMPRESS | ||
513 | { | ||
514 | .compress = compress_lz4, | ||
515 | .decompress = decompress_lz4, | ||
516 | .allocate = allocate_lz4, | ||
517 | .free = free_lz4, | ||
518 | .name = "lz4", | ||
519 | }, | ||
520 | #endif | ||
521 | #ifdef CONFIG_PSTORE_LZ4HC_COMPRESS | ||
522 | { | ||
523 | .compress = compress_lz4hc, | ||
524 | .decompress = decompress_lz4, | ||
525 | .allocate = allocate_lz4hc, | ||
526 | .free = free_lz4, | ||
527 | .name = "lz4hc", | ||
528 | }, | ||
534 | #endif | 529 | #endif |
530 | #ifdef CONFIG_PSTORE_842_COMPRESS | ||
531 | { | ||
532 | .compress = compress_842, | ||
533 | .decompress = decompress_842, | ||
534 | .allocate = allocate_842, | ||
535 | .free = free_842, | ||
536 | .name = "842", | ||
537 | }, | ||
538 | #endif | ||
539 | { } | ||
540 | }; | ||
535 | 541 | ||
536 | static int pstore_compress(const void *in, void *out, | 542 | static int pstore_compress(const void *in, void *out, |
537 | size_t inlen, size_t outlen) | 543 | size_t inlen, size_t outlen) |
@@ -553,7 +559,6 @@ static int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen) | |||
553 | static void allocate_buf_for_compression(void) | 559 | static void allocate_buf_for_compression(void) |
554 | { | 560 | { |
555 | if (zbackend) { | 561 | if (zbackend) { |
556 | pr_info("using %s compression\n", zbackend->name); | ||
557 | zbackend->allocate(); | 562 | zbackend->allocate(); |
558 | } else { | 563 | } else { |
559 | pr_err("allocate compression buffer error!\n"); | 564 | pr_err("allocate compression buffer error!\n"); |
@@ -1022,5 +1027,24 @@ static void pstore_timefunc(struct timer_list *unused) | |||
1022 | jiffies + msecs_to_jiffies(pstore_update_ms)); | 1027 | jiffies + msecs_to_jiffies(pstore_update_ms)); |
1023 | } | 1028 | } |
1024 | 1029 | ||
1030 | void __init pstore_choose_compression(void) | ||
1031 | { | ||
1032 | const struct pstore_zbackend *step; | ||
1033 | |||
1034 | if (!compress) | ||
1035 | return; | ||
1036 | |||
1037 | for (step = zbackends; step->name; step++) { | ||
1038 | if (!strcmp(compress, step->name)) { | ||
1039 | zbackend = step; | ||
1040 | pr_info("using %s compression\n", zbackend->name); | ||
1041 | return; | ||
1042 | } | ||
1043 | } | ||
1044 | } | ||
1045 | |||
1046 | module_param(compress, charp, 0444); | ||
1047 | MODULE_PARM_DESC(compress, "Pstore compression to use"); | ||
1048 | |||
1025 | module_param(backend, charp, 0444); | 1049 | module_param(backend, charp, 0444); |
1026 | MODULE_PARM_DESC(backend, "Pstore backend to use"); | 1050 | MODULE_PARM_DESC(backend, "Pstore backend to use"); |