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 /tools/perf/util/lzma.c | |
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>
Diffstat (limited to 'tools/perf/util/lzma.c')
-rw-r--r-- | tools/perf/util/lzma.c | 95 |
1 files changed, 95 insertions, 0 deletions
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 | } | ||