diff options
author | Jiri Olsa <jolsa@kernel.org> | 2015-01-29 07:29:39 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-21 13:53:40 -0400 |
commit | 80a32e5b498a7547073e5e4b2b804edc7219979d (patch) | |
tree | efec16463880cf50866b2b5487df32450a96c176 | |
parent | 6c6f0f6164fbf7a1667378496ee36ae48c18a9d6 (diff) |
perf tools: Add lzma decompression support for kernel module
In short, Fedora compresses kernel modules now (since version 21) with
lzma compression.
Adding lzma decompress support into the dso.c:compressions array
introduced by Namhyung earlier.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-2glp65kdtbrk0gblmirsjsnt@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Makefile.perf | 2 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 11 | ||||
-rw-r--r-- | tools/perf/util/Build | 1 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 3 | ||||
-rw-r--r-- | tools/perf/util/lzma.c | 95 | ||||
-rw-r--r-- | tools/perf/util/util.h | 4 |
6 files changed, 116 insertions, 0 deletions
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index d5b9e0dae334..e9925e6ad1d0 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -71,6 +71,8 @@ include config/utilities.mak | |||
71 | # | 71 | # |
72 | # Define NO_LIBBABELTRACE if you do not want libbabeltrace support | 72 | # Define NO_LIBBABELTRACE if you do not want libbabeltrace support |
73 | # for CTF data format. | 73 | # for CTF data format. |
74 | # | ||
75 | # Define NO_LZMA if you do not want to support compressed (xz) kernel modules | ||
74 | 76 | ||
75 | ifeq ($(srctree),) | 77 | ifeq ($(srctree),) |
76 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | 78 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 6d1918a6b83b..cd121dfc4de9 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -541,6 +541,17 @@ ifndef NO_ZLIB | |||
541 | endif | 541 | endif |
542 | endif | 542 | endif |
543 | 543 | ||
544 | ifndef NO_LZMA | ||
545 | ifeq ($(feature-lzma), 1) | ||
546 | CFLAGS += -DHAVE_LZMA_SUPPORT | ||
547 | EXTLIBS += -llzma | ||
548 | $(call detected,CONFIG_LZMA) | ||
549 | else | ||
550 | msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev); | ||
551 | NO_LZMA := 1 | ||
552 | endif | ||
553 | endif | ||
554 | |||
544 | ifndef NO_BACKTRACE | 555 | ifndef NO_BACKTRACE |
545 | ifeq ($(feature-backtrace), 1) | 556 | ifeq ($(feature-backtrace), 1) |
546 | CFLAGS += -DHAVE_BACKTRACE_SUPPORT | 557 | CFLAGS += -DHAVE_BACKTRACE_SUPPORT |
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 972a6e0da7ad..797490a40075 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
@@ -94,6 +94,7 @@ libperf-y += scripting-engines/ | |||
94 | 94 | ||
95 | libperf-$(CONFIG_PERF_REGS) += perf_regs.o | 95 | libperf-$(CONFIG_PERF_REGS) += perf_regs.o |
96 | libperf-$(CONFIG_ZLIB) += zlib.o | 96 | libperf-$(CONFIG_ZLIB) += zlib.o |
97 | libperf-$(CONFIG_LZMA) += lzma.o | ||
97 | 98 | ||
98 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" | 99 | CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" |
99 | CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" | 100 | CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" |
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 814554d1b857..be368414036c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -148,6 +148,9 @@ static const struct { | |||
148 | #ifdef HAVE_ZLIB_SUPPORT | 148 | #ifdef HAVE_ZLIB_SUPPORT |
149 | { "gz", gzip_decompress_to_file }, | 149 | { "gz", gzip_decompress_to_file }, |
150 | #endif | 150 | #endif |
151 | #ifdef HAVE_LZMA_SUPPORT | ||
152 | { "xz", lzma_decompress_to_file }, | ||
153 | #endif | ||
151 | { NULL, NULL }, | 154 | { NULL, NULL }, |
152 | }; | 155 | }; |
153 | 156 | ||
diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c new file mode 100644 index 000000000000..95a1acb61245 --- /dev/null +++ b/tools/perf/util/lzma.c | |||
@@ -0,0 +1,95 @@ | |||
1 | #include <lzma.h> | ||
2 | #include <stdio.h> | ||
3 | #include <linux/compiler.h> | ||
4 | #include "util.h" | ||
5 | #include "debug.h" | ||
6 | |||
7 | #define BUFSIZE 8192 | ||
8 | |||
9 | static const char *lzma_strerror(lzma_ret ret) | ||
10 | { | ||
11 | switch ((int) ret) { | ||
12 | case LZMA_MEM_ERROR: | ||
13 | return "Memory allocation failed"; | ||
14 | case LZMA_OPTIONS_ERROR: | ||
15 | return "Unsupported decompressor flags"; | ||
16 | case LZMA_FORMAT_ERROR: | ||
17 | return "The input is not in the .xz format"; | ||
18 | case LZMA_DATA_ERROR: | ||
19 | return "Compressed file is corrupt"; | ||
20 | case LZMA_BUF_ERROR: | ||
21 | return "Compressed file is truncated or otherwise corrupt"; | ||
22 | default: | ||
23 | return "Unknown error, possibly a bug"; | ||
24 | } | ||
25 | } | ||
26 | |||
27 | int lzma_decompress_to_file(const char *input, int output_fd) | ||
28 | { | ||
29 | lzma_action action = LZMA_RUN; | ||
30 | lzma_stream strm = LZMA_STREAM_INIT; | ||
31 | lzma_ret ret; | ||
32 | |||
33 | u8 buf_in[BUFSIZE]; | ||
34 | u8 buf_out[BUFSIZE]; | ||
35 | FILE *infile; | ||
36 | |||
37 | infile = fopen(input, "rb"); | ||
38 | if (!infile) { | ||
39 | pr_err("lzma: fopen failed on %s: '%s'\n", | ||
40 | input, strerror(errno)); | ||
41 | return -1; | ||
42 | } | ||
43 | |||
44 | ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED); | ||
45 | if (ret != LZMA_OK) { | ||
46 | pr_err("lzma: lzma_stream_decoder failed %s (%d)\n", | ||
47 | lzma_strerror(ret), ret); | ||
48 | return -1; | ||
49 | } | ||
50 | |||
51 | strm.next_in = NULL; | ||
52 | strm.avail_in = 0; | ||
53 | strm.next_out = buf_out; | ||
54 | strm.avail_out = sizeof(buf_out); | ||
55 | |||
56 | while (1) { | ||
57 | if (strm.avail_in == 0 && !feof(infile)) { | ||
58 | strm.next_in = buf_in; | ||
59 | strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile); | ||
60 | |||
61 | if (ferror(infile)) { | ||
62 | pr_err("lzma: read error: %s\n", strerror(errno)); | ||
63 | return -1; | ||
64 | } | ||
65 | |||
66 | if (feof(infile)) | ||
67 | action = LZMA_FINISH; | ||
68 | } | ||
69 | |||
70 | ret = lzma_code(&strm, action); | ||
71 | |||
72 | if (strm.avail_out == 0 || ret == LZMA_STREAM_END) { | ||
73 | ssize_t write_size = sizeof(buf_out) - strm.avail_out; | ||
74 | |||
75 | if (writen(output_fd, buf_out, write_size) != write_size) { | ||
76 | pr_err("lzma: write error: %s\n", strerror(errno)); | ||
77 | return -1; | ||
78 | } | ||
79 | |||
80 | strm.next_out = buf_out; | ||
81 | strm.avail_out = sizeof(buf_out); | ||
82 | } | ||
83 | |||
84 | if (ret != LZMA_OK) { | ||
85 | if (ret == LZMA_STREAM_END) | ||
86 | return 0; | ||
87 | |||
88 | pr_err("lzma: failed %s\n", lzma_strerror(ret)); | ||
89 | return -1; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | fclose(infile); | ||
94 | return 0; | ||
95 | } | ||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index fbd598afc606..1ff23e04ad27 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -329,4 +329,8 @@ bool find_process(const char *name); | |||
329 | int gzip_decompress_to_file(const char *input, int output_fd); | 329 | int gzip_decompress_to_file(const char *input, int output_fd); |
330 | #endif | 330 | #endif |
331 | 331 | ||
332 | #ifdef HAVE_LZMA_SUPPORT | ||
333 | int lzma_decompress_to_file(const char *input, int output_fd); | ||
334 | #endif | ||
335 | |||
332 | #endif /* GIT_COMPAT_UTIL_H */ | 336 | #endif /* GIT_COMPAT_UTIL_H */ |