summarylogtreecommitdiffstats
path: root/0002-add-zstd-compressed-module-support.patch
diff options
context:
space:
mode:
Diffstat (limited to '0002-add-zstd-compressed-module-support.patch')
-rw-r--r--0002-add-zstd-compressed-module-support.patch187
1 files changed, 187 insertions, 0 deletions
diff --git a/0002-add-zstd-compressed-module-support.patch b/0002-add-zstd-compressed-module-support.patch
new file mode 100644
index 000000000000..39ad80c047b4
--- /dev/null
+++ b/0002-add-zstd-compressed-module-support.patch
@@ -0,0 +1,187 @@
+diff --git a/Makefile.am b/Makefile.am
+index 47505c1..155456f 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -89,7 +89,7 @@ libkmod_libkmod_la_DEPENDENCIES = \
+ ${top_srcdir}/libkmod/libkmod.sym
+ libkmod_libkmod_la_LIBADD = \
+ shared/libshared.la \
+- ${liblzma_LIBS} ${zlib_LIBS} ${libcrypto_LIBS}
++ ${libzstd_LIBS} ${liblzma_LIBS} ${zlib_LIBS} ${libcrypto_LIBS}
+
+ noinst_LTLIBRARIES += libkmod/libkmod-internal.la
+ libkmod_libkmod_internal_la_SOURCES = $(libkmod_libkmod_la_SOURCES)
+diff --git a/configure.ac b/configure.ac
+index e885d79..a286159 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -83,6 +83,17 @@ AC_ARG_WITH([rootlibdir],
+ [], [with_rootlibdir=$libdir])
+ AC_SUBST([rootlibdir], [$with_rootlibdir])
+
++AC_ARG_WITH([zstd],
++ AS_HELP_STRING([--with-zstd], [handle Zstd-compressed modules @<:@default=disabled@:>@]),
++ [], [with_zstd=no])
++AS_IF([test "x$with_zstd" != "xno"], [
++ PKG_CHECK_MODULES([libzstd], [libzstd >= 1.4.4])
++ AC_DEFINE([ENABLE_ZSTD], [1], [Enable Zstd for modules.])
++], [
++ AC_MSG_NOTICE([Zstd support not requested])
++])
++CC_FEATURE_APPEND([with_features], [with_zstd], [ZSTD])
++
+ AC_ARG_WITH([xz],
+ AS_HELP_STRING([--with-xz], [handle Xz-compressed modules @<:@default=disabled@:>@]),
+ [], [with_xz=no])
+@@ -307,7 +318,7 @@ AC_MSG_RESULT([
+ tools: ${enable_tools}
+ python bindings: ${enable_python}
+ logging: ${enable_logging}
+- compression: xz=${with_xz} zlib=${with_zlib}
++ compression: zstd=${with_zstd} xz=${with_xz} zlib=${with_zlib}
+ debug: ${enable_debug}
+ coverage: ${enable_coverage}
+ doc: ${enable_gtk_doc}
+diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c
+index 5eeba6a..2575b01 100644
+--- a/libkmod/libkmod-file.c
++++ b/libkmod/libkmod-file.c
+@@ -32,7 +32,9 @@
+ #ifdef ENABLE_ZLIB
+ #include <zlib.h>
+ #endif
+-
++#ifdef ENABLE_ZSTD
++#include <zstd.h>
++#endif
+ #include <shared/util.h>
+
+ #include "libkmod.h"
+@@ -45,6 +47,9 @@ struct file_ops {
+ };
+
+ struct kmod_file {
++#ifdef ENABLE_ZSTD
++ bool zstd_used;
++#endif
+ #ifdef ENABLE_XZ
+ bool xz_used;
+ #endif
+@@ -60,6 +65,79 @@ struct kmod_file {
+ struct kmod_elf *elf;
+ };
+
++#ifdef ENABLE_ZSTD
++static int zstd_uncompress(ZSTD_DStream *strm, struct kmod_file *file) {
++ uint8_t in_buf[BUFSIZ], out_buf[BUFSIZ];
++ ZSTD_outBuffer output = { out_buf, sizeof(out_buf), 0 };
++ ZSTD_inBuffer input = { in_buf, 0, 0 };
++ void *p = NULL;
++ int ret = 0;
++ size_t total = 0;
++
++ while(true) {
++ size_t sz;
++ if (input.pos == input.size) {
++ ssize_t rdret = read(file->fd, in_buf, sizeof(in_buf));
++ if (rdret < 0) {
++ ret = -errno;
++ goto out;
++ }
++ input.size = rdret;
++ input.pos = 0;
++ }
++ if (input.size == 0) {
++ break;
++ }
++ sz = ZSTD_decompressStream(strm, &output, &input);
++ if (ZSTD_isError(sz)) {
++ ret = -1;
++ goto out;
++ }
++ if (output.pos == output.size || sz == 0) {
++ size_t write_size = output.pos;
++ char *tmp = realloc(p, total + write_size);
++ if (tmp == NULL) {
++ ret = -errno;
++ goto out;
++ }
++ memcpy(tmp + total, out_buf, write_size);
++ total += write_size;
++ p = tmp;
++ if (output.pos == output.size) {
++ output.pos = 0;
++ }
++ }
++ }
++ file->zstd_used = true;
++ file->memory = p;
++ file->size = total;
++ return 0;
++out:
++ free(p);
++ return ret;
++}
++
++static int load_zstd(struct kmod_file *file)
++{
++ ZSTD_DStream* strm = ZSTD_createDStream();
++ int ret;
++ ZSTD_initDStream(strm);
++
++ ret = zstd_uncompress(strm, file);
++ ZSTD_freeDStream(strm);
++ return ret;
++}
++
++static void unload_zstd(struct kmod_file *file)
++{
++ if (!file->zstd_used)
++ return;
++ free(file->memory);
++}
++
++static const char magic_zstd[] = {0x28, 0xb5, 0x2f, 0xfd};
++#endif
++
+ #ifdef ENABLE_XZ
+ static void xz_uncompress_belch(struct kmod_file *file, lzma_ret ret)
+ {
+@@ -238,6 +316,9 @@ static const struct comp_type {
+ const char *magic_bytes;
+ const struct file_ops ops;
+ } comp_types[] = {
++#ifdef ENABLE_ZSTD
++ {sizeof(magic_zstd), magic_zstd, {load_zstd, unload_zstd}},
++#endif
+ #ifdef ENABLE_XZ
+ {sizeof(magic_xz), magic_xz, {load_xz, unload_xz}},
+ #endif
+diff --git a/shared/util.c b/shared/util.c
+index fd2028d..b487b5f 100644
+--- a/shared/util.c
++++ b/shared/util.c
+@@ -45,6 +45,9 @@ static const struct kmod_ext {
+ #endif
+ #ifdef ENABLE_XZ
+ {".ko.xz", sizeof(".ko.xz") - 1},
++#endif
++#ifdef ENABLE_ZSTD
++ {".ko.zst", sizeof(".ko.zst") - 1},
+ #endif
+ { }
+ };
+diff --git a/testsuite/test-util.c b/testsuite/test-util.c
+index 5e25e58..621446b 100644
+--- a/testsuite/test-util.c
++++ b/testsuite/test-util.c
+@@ -156,6 +156,9 @@ static int test_path_ends_with_kmod_ext(const struct test *t)
+ #endif
+ #ifdef ENABLE_XZ
+ { "/bla.ko.xz", true },
++#endif
++#ifdef ENABLE_ZSTD
++ { "/bla.ko.zst", true },
+ #endif
+ { "/bla.ko.x", false },
+ { "/bla.ko.", false },