1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-21 02:50:18 +03:00

basic: expose compression level argument in compress_blob functions

This commit is contained in:
Andrii Chubatiuk 2024-10-18 20:43:31 +03:00
parent aedef65e2b
commit 91d6f1ee53
6 changed files with 42 additions and 25 deletions

View File

@ -8,6 +8,10 @@
#include <sys/types.h>
#include <unistd.h>
#if HAVE_LZ4
#include <lz4hc.h>
#endif
#if HAVE_XZ
#include <lzma.h>
#endif
@ -43,6 +47,7 @@ static DLSYM_PROTOTYPE(LZ4F_freeCompressionContext) = NULL;
static DLSYM_PROTOTYPE(LZ4F_freeDecompressionContext) = NULL;
static DLSYM_PROTOTYPE(LZ4F_isError) = NULL;
DLSYM_PROTOTYPE(LZ4_compress_default) = NULL;
DLSYM_PROTOTYPE(LZ4_compress_HC) = NULL;
DLSYM_PROTOTYPE(LZ4_decompress_safe) = NULL;
DLSYM_PROTOTYPE(LZ4_decompress_safe_partial) = NULL;
DLSYM_PROTOTYPE(LZ4_versionNumber) = NULL;
@ -94,6 +99,7 @@ static DLSYM_PROTOTYPE(lzma_easy_encoder) = NULL;
static DLSYM_PROTOTYPE(lzma_end) = NULL;
static DLSYM_PROTOTYPE(lzma_stream_buffer_encode) = NULL;
static DLSYM_PROTOTYPE(lzma_stream_decoder) = NULL;
static DLSYM_PROTOTYPE(lzma_lzma_preset) = NULL;
/* We can't just do _cleanup_(sym_lzma_end) because a compiler bug makes
* this fail with:
@ -145,12 +151,13 @@ int dlopen_lzma(void) {
DLSYM_ARG(lzma_easy_encoder),
DLSYM_ARG(lzma_end),
DLSYM_ARG(lzma_stream_buffer_encode),
DLSYM_ARG(lzma_lzma_preset),
DLSYM_ARG(lzma_stream_decoder));
}
#endif
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
assert(src);
assert(src_size > 0);
@ -159,12 +166,12 @@ int compress_blob_xz(const void *src, uint64_t src_size,
assert(dst_size);
#if HAVE_XZ
static const lzma_options_lzma opt = {
lzma_options_lzma opt = {
1u << 20u, NULL, 0, LZMA_LC_DEFAULT, LZMA_LP_DEFAULT,
LZMA_PB_DEFAULT, LZMA_MODE_FAST, 128, LZMA_MF_HC3, 4
};
static const lzma_filter filters[] = {
{ LZMA_FILTER_LZMA2, (lzma_options_lzma*) &opt },
lzma_filter filters[] = {
{ LZMA_FILTER_LZMA2, &opt },
{ LZMA_VLI_UNKNOWN, NULL }
};
lzma_ret ret;
@ -175,13 +182,19 @@ int compress_blob_xz(const void *src, uint64_t src_size,
if (r < 0)
return r;
if (level >= 0) {
r = sym_lzma_lzma_preset(&opt, (uint32_t) level);
if (r < 0)
return r;
}
/* Returns < 0 if we couldn't compress the data or the
* compressed result is longer than the original */
if (src_size < 80)
return -ENOBUFS;
ret = sym_lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL,
ret = sym_lzma_stream_buffer_encode(filters, LZMA_CHECK_NONE, NULL,
src, src_size, dst, &out_pos, dst_alloc_size);
if (ret != LZMA_OK)
return -ENOBUFS;
@ -214,6 +227,7 @@ int dlopen_lz4(void) {
DLSYM_ARG(LZ4F_freeDecompressionContext),
DLSYM_ARG(LZ4F_isError),
DLSYM_ARG(LZ4_compress_default),
DLSYM_ARG(LZ4_compress_HC),
DLSYM_ARG(LZ4_decompress_safe),
DLSYM_ARG(LZ4_decompress_safe_partial),
DLSYM_ARG(LZ4_versionNumber));
@ -221,7 +235,7 @@ int dlopen_lz4(void) {
#endif
int compress_blob_lz4(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
assert(src);
assert(src_size > 0);
@ -241,7 +255,10 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
if (src_size < 9)
return -ENOBUFS;
r = sym_LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
if (level <= 0)
r = sym_LZ4_compress_default(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8);
else
r = sym_LZ4_compress_HC(src, (char*)dst + 8, src_size, (int) dst_alloc_size - 8, level);
if (r <= 0)
return -ENOBUFS;
@ -285,7 +302,7 @@ int dlopen_zstd(void) {
int compress_blob_zstd(
const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
assert(src);
assert(src_size > 0);
@ -301,7 +318,7 @@ int compress_blob_zstd(
if (r < 0)
return r;
k = sym_ZSTD_compress(dst, dst_alloc_size, src, src_size, 0);
k = sym_ZSTD_compress(dst, dst_alloc_size, src, src_size, level < 0 ? 0 : level);
if (sym_ZSTD_isError(k))
return zstd_ret_to_errno(k);

View File

@ -28,11 +28,11 @@ Compression compression_from_string(const char *compression);
bool compression_supported(Compression c);
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
int compress_blob_lz4(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
int compress_blob_zstd(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
int decompress_blob_xz(const void *src, uint64_t src_size,
void **dst, size_t* dst_size, size_t dst_max);
@ -90,15 +90,15 @@ int dlopen_lzma(void);
static inline int compress_blob(
Compression compression,
const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
void *dst, size_t dst_alloc_size, size_t *dst_size, int level) {
switch (compression) {
case COMPRESSION_ZSTD:
return compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
return compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size, level);
case COMPRESSION_LZ4:
return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size, level);
case COMPRESSION_XZ:
return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size, level);
default:
return -EOPNOTSUPP;
}

View File

@ -42,7 +42,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
size_t csize;
r = compress_blob(alg, h->data, data_len, buf, size, &csize);
r = compress_blob(alg, h->data, data_len, buf, size, &csize, /* level = */ -1);
if (r < 0) {
log_error_errno(r, "Compression failed: %m");
return 0;

View File

@ -1810,7 +1810,7 @@ static int maybe_compress_payload(JournalFile *f, uint8_t *dst, const uint8_t *s
if (c == COMPRESSION_NONE || size < f->compress_threshold_bytes)
return 0;
r = compress_blob(c, src, size, dst, size - 1, rsize);
r = compress_blob(c, src, size, dst, size - 1, rsize, /* level = */ -1);
if (r < 0)
return log_debug_errno(r, "Failed to compress data object using %s, ignoring: %m", compression_to_string(c));

View File

@ -13,7 +13,7 @@
#include "tests.h"
typedef int (compress_t)(const void *src, uint64_t src_size, void *dst,
size_t dst_alloc_size, size_t *dst_size);
size_t dst_alloc_size, size_t *dst_size, int level);
typedef int (decompress_t)(const void *src, uint64_t src_size,
void **dst, size_t* dst_size, size_t dst_max);
@ -100,7 +100,7 @@ static void test_compress_decompress(const char* label, const char* type,
memzero(buf, MIN(size + 1000, MAX_SIZE));
r = compress(text, size, buf, size, &j);
r = compress(text, size, buf, size, &j, /* level = */ -1);
/* assume compression must be successful except for small or random inputs */
assert_se(r >= 0 || (size < 2048 && r == -ENOBUFS) || streq(type, "random"));

View File

@ -33,7 +33,7 @@
#define HUGE_SIZE (4096*1024)
typedef int (compress_blob_t)(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
void *dst, size_t dst_alloc_size, size_t *dst_size, int level);
typedef int (decompress_blob_t)(const void *src, uint64_t src_size,
void **dst,
size_t* dst_size, size_t dst_max);
@ -62,7 +62,7 @@ _unused_ static void test_compress_decompress(
log_info("/* testing %s %s blob compression/decompression */",
compression, data);
r = compress(data, data_len, compressed, sizeof(compressed), &csize);
r = compress(data, data_len, compressed, sizeof(compressed), &csize, /* level = */ -1);
if (r == -ENOBUFS) {
log_info_errno(r, "compression failed: %m");
assert_se(may_fail);
@ -111,14 +111,14 @@ _unused_ static void test_decompress_startswith(const char *compression,
compressed = compressed1 = malloc(BUFSIZE_1);
assert_se(compressed1);
r = compress(data, data_len, compressed, BUFSIZE_1, &csize);
r = compress(data, data_len, compressed, BUFSIZE_1, &csize, /* level = */ -1);
if (r == -ENOBUFS) {
log_info_errno(r, "compression failed: %m");
assert_se(may_fail);
compressed = compressed2 = malloc(BUFSIZE_2);
assert_se(compressed2);
r = compress(data, data_len, compressed, BUFSIZE_2, &csize);
r = compress(data, data_len, compressed, BUFSIZE_2, &csize, /* level = */ -1);
}
assert_se(r >= 0);
@ -150,7 +150,7 @@ _unused_ static void test_decompress_startswith_short(const char *compression,
log_info("/* %s with %s */", __func__, compression);
r = compress(TEXT, sizeof TEXT, buf, sizeof buf, &csize);
r = compress(TEXT, sizeof TEXT, buf, sizeof buf, &csize, /* level = */ -1);
assert_se(r >= 0);
for (size_t i = 1; i < strlen(TEXT); i++) {