Commit 80a32e5b authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

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: default avatarJiri Olsa <jolsa@kernel.org>
Acked-by: default avatarNamhyung 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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 6c6f0f61
...@@ -71,6 +71,8 @@ include config/utilities.mak ...@@ -71,6 +71,8 @@ include config/utilities.mak
# #
# Define NO_LIBBABELTRACE if you do not want libbabeltrace support # Define NO_LIBBABELTRACE if you do not want libbabeltrace support
# for CTF data format. # for CTF data format.
#
# Define NO_LZMA if you do not want to support compressed (xz) kernel modules
ifeq ($(srctree),) ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd))) srctree := $(patsubst %/,%,$(dir $(shell pwd)))
......
...@@ -541,6 +541,17 @@ ifndef NO_ZLIB ...@@ -541,6 +541,17 @@ ifndef NO_ZLIB
endif endif
endif endif
ifndef NO_LZMA
ifeq ($(feature-lzma), 1)
CFLAGS += -DHAVE_LZMA_SUPPORT
EXTLIBS += -llzma
$(call detected,CONFIG_LZMA)
else
msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev);
NO_LZMA := 1
endif
endif
ifndef NO_BACKTRACE ifndef NO_BACKTRACE
ifeq ($(feature-backtrace), 1) ifeq ($(feature-backtrace), 1)
CFLAGS += -DHAVE_BACKTRACE_SUPPORT CFLAGS += -DHAVE_BACKTRACE_SUPPORT
......
...@@ -94,6 +94,7 @@ libperf-y += scripting-engines/ ...@@ -94,6 +94,7 @@ libperf-y += scripting-engines/
libperf-$(CONFIG_PERF_REGS) += perf_regs.o libperf-$(CONFIG_PERF_REGS) += perf_regs.o
libperf-$(CONFIG_ZLIB) += zlib.o libperf-$(CONFIG_ZLIB) += zlib.o
libperf-$(CONFIG_LZMA) += lzma.o
CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))" CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))"
......
...@@ -147,6 +147,9 @@ static const struct { ...@@ -147,6 +147,9 @@ static const struct {
} compressions[] = { } compressions[] = {
#ifdef HAVE_ZLIB_SUPPORT #ifdef HAVE_ZLIB_SUPPORT
{ "gz", gzip_decompress_to_file }, { "gz", gzip_decompress_to_file },
#endif
#ifdef HAVE_LZMA_SUPPORT
{ "xz", lzma_decompress_to_file },
#endif #endif
{ NULL, NULL }, { NULL, NULL },
}; };
......
#include <lzma.h>
#include <stdio.h>
#include <linux/compiler.h>
#include "util.h"
#include "debug.h"
#define BUFSIZE 8192
static const char *lzma_strerror(lzma_ret ret)
{
switch ((int) ret) {
case LZMA_MEM_ERROR:
return "Memory allocation failed";
case LZMA_OPTIONS_ERROR:
return "Unsupported decompressor flags";
case LZMA_FORMAT_ERROR:
return "The input is not in the .xz format";
case LZMA_DATA_ERROR:
return "Compressed file is corrupt";
case LZMA_BUF_ERROR:
return "Compressed file is truncated or otherwise corrupt";
default:
return "Unknown error, possibly a bug";
}
}
int lzma_decompress_to_file(const char *input, int output_fd)
{
lzma_action action = LZMA_RUN;
lzma_stream strm = LZMA_STREAM_INIT;
lzma_ret ret;
u8 buf_in[BUFSIZE];
u8 buf_out[BUFSIZE];
FILE *infile;
infile = fopen(input, "rb");
if (!infile) {
pr_err("lzma: fopen failed on %s: '%s'\n",
input, strerror(errno));
return -1;
}
ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
if (ret != LZMA_OK) {
pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
lzma_strerror(ret), ret);
return -1;
}
strm.next_in = NULL;
strm.avail_in = 0;
strm.next_out = buf_out;
strm.avail_out = sizeof(buf_out);
while (1) {
if (strm.avail_in == 0 && !feof(infile)) {
strm.next_in = buf_in;
strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
if (ferror(infile)) {
pr_err("lzma: read error: %s\n", strerror(errno));
return -1;
}
if (feof(infile))
action = LZMA_FINISH;
}
ret = lzma_code(&strm, action);
if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
ssize_t write_size = sizeof(buf_out) - strm.avail_out;
if (writen(output_fd, buf_out, write_size) != write_size) {
pr_err("lzma: write error: %s\n", strerror(errno));
return -1;
}
strm.next_out = buf_out;
strm.avail_out = sizeof(buf_out);
}
if (ret != LZMA_OK) {
if (ret == LZMA_STREAM_END)
return 0;
pr_err("lzma: failed %s\n", lzma_strerror(ret));
return -1;
}
}
fclose(infile);
return 0;
}
...@@ -329,4 +329,8 @@ bool find_process(const char *name); ...@@ -329,4 +329,8 @@ bool find_process(const char *name);
int gzip_decompress_to_file(const char *input, int output_fd); int gzip_decompress_to_file(const char *input, int output_fd);
#endif #endif
#ifdef HAVE_LZMA_SUPPORT
int lzma_decompress_to_file(const char *input, int output_fd);
#endif
#endif /* GIT_COMPAT_UTIL_H */ #endif /* GIT_COMPAT_UTIL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment