1
0
mirror of https://github.com/systemd/systemd synced 2026-04-26 00:45:09 +02:00

Compare commits

..

9 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek
4d5713bb7e
Merge pull request #23119 from yuwata/test-sd-device-exclude-bdi
test: exclude "bdi" subsystem
2022-04-27 16:56:53 +02:00
Zbigniew Jędrzejewski-Szmek
3d8a7e6f51
Merge pull request #23131 from poettering/shared-compress
move compress.[ch] → src/basic/
2022-04-27 10:47:54 +02:00
Yu Watanabe
ff56124b11 test: exclude "bdi" subsystem and loop block devices
On several CI environments, it seems that some loop block devices and
corresponding bdi devices are sometimes removed during the test is
running. Let's exclude them.

Fixes #22970.
2022-04-27 16:32:42 +09:00
Yu Watanabe
9409710097 sd-device-enumerator: introduce sd_device_enumerator_add_nomatch_sysname() 2022-04-27 16:32:42 +09:00
Yu Watanabe
c11810ed30 sd-device-enumerator: use set_fnmatch() 2022-04-27 16:32:42 +09:00
Yu Watanabe
d25d4f189c set: introduce set_fnmatch() 2022-04-27 16:32:15 +09:00
Lennart Poettering
d4cc5c8037 journal-verify: tighten check for compression of non-objects 2022-04-26 21:55:49 +02:00
Lennart Poettering
4d698d12de compress: make Compression a regular non-sparse enum
Given we have two different types for the journal object flags and the
Compression enum, let's make the latter a regular non-sparse enum, and
thus remove some surprises. We have to convert anyway between the two,
and already do via COMPRESSION_FROM_OBJECT().
2022-04-26 21:55:49 +02:00
Lennart Poettering
acc50c92eb basic: move compress.[ch] → src/basic/
The compression helpers are used both in journal code and in coredump
code, and there's a good chance we'll use them later for other stuff.

Let's hence move them into src/basic/, to make them a proper internal
API we can use from everywhere where that's desirable. (pstore might be
a candidate, for example)

No real code changes, just some moving around, build system
rearrangements, and stripping of journal-def.h inclusion.
2022-04-26 21:45:03 +02:00
24 changed files with 296 additions and 159 deletions

View File

@ -1472,7 +1472,7 @@ elif compression == 'xz' and not have_xz
endif
conf.set('DEFAULT_COMPRESSION',
compression == 'none' ? 0 :
'OBJECT_COMPRESSED_@0@'.format(compression.to_upper()))
'COMPRESSION_@0@'.format(compression.to_upper()))
want_xkbcommon = get_option('xkbcommon')
if want_xkbcommon != 'false' and not skip_deps
@ -1901,13 +1901,11 @@ libsystemd = shared_library(
link_args : ['-shared',
'-Wl,--version-script=' + libsystemd_sym_path],
link_with : [libbasic,
libbasic_gcrypt],
libbasic_gcrypt,
libbasic_compress],
link_whole : [libsystemd_static],
dependencies : [threads,
librt,
libxz,
libzstd,
liblz4],
librt],
link_depends : libsystemd_sym,
install : true,
install_dir : rootlibdir)
@ -1917,6 +1915,7 @@ install_libsystemd_static = static_library(
libsystemd_sources,
basic_sources,
basic_gcrypt_sources,
basic_compress_sources,
fundamental_sources,
disable_mempool_c,
include_directories : libsystemd_includes,
@ -3031,7 +3030,8 @@ if conf.get('ENABLE_COREDUMP') == 1
'systemd-coredump',
systemd_coredump_sources,
include_directories : includes,
link_with : [libshared],
link_with : [libshared,
libbasic_compress],
dependencies : [threads,
libacl,
libxz,
@ -3045,7 +3045,8 @@ if conf.get('ENABLE_COREDUMP') == 1
'coredumpctl',
coredumpctl_sources,
include_directories : includes,
link_with : [libshared],
link_with : [libshared,
libbasic_compress],
dependencies : [threads,
libxz,
liblz4,

View File

@ -27,7 +27,6 @@
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
#include "journal-def.h"
#include "macro.h"
#include "sparse-endian.h"
#include "string-table.h"
@ -58,15 +57,14 @@ static int zstd_ret_to_errno(size_t ret) {
#define ALIGN_8(l) ALIGN_TO(l, sizeof(size_t))
static const char* const object_compressed_table[_OBJECT_COMPRESSED_MAX] = {
[OBJECT_COMPRESSED_XZ] = "XZ",
[OBJECT_COMPRESSED_LZ4] = "LZ4",
[OBJECT_COMPRESSED_ZSTD] = "ZSTD",
/* If we add too many more entries here, it's going to grow quite large (and be mostly sparse), since
* the array key is actually a bitmask, not a plain enum */
static const char* const compression_table[_COMPRESSION_MAX] = {
[COMPRESSION_NONE] = "NONE",
[COMPRESSION_XZ] = "XZ",
[COMPRESSION_LZ4] = "LZ4",
[COMPRESSION_ZSTD] = "ZSTD",
};
DEFINE_STRING_TABLE_LOOKUP(object_compressed, int);
DEFINE_STRING_TABLE_LOOKUP(compression, Compression);
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
@ -100,7 +98,7 @@ int compress_blob_xz(const void *src, uint64_t src_size,
return -ENOBUFS;
*dst_size = out_pos;
return OBJECT_COMPRESSED_XZ;
return COMPRESSION_XZ;
#else
return -EPROTONOSUPPORT;
#endif
@ -130,7 +128,7 @@ int compress_blob_lz4(const void *src, uint64_t src_size,
unaligned_write_le64(dst, src_size);
*dst_size = r + 8;
return OBJECT_COMPRESSED_LZ4;
return COMPRESSION_LZ4;
#else
return -EPROTONOSUPPORT;
#endif
@ -153,7 +151,7 @@ int compress_blob_zstd(
return zstd_ret_to_errno(k);
*dst_size = k;
return OBJECT_COMPRESSED_ZSTD;
return COMPRESSION_ZSTD;
#else
return -EPROTONOSUPPORT;
#endif
@ -313,22 +311,22 @@ int decompress_blob_zstd(
}
int decompress_blob(
int compression,
Compression compression,
const void *src,
uint64_t src_size,
void **dst,
size_t* dst_size,
size_t dst_max) {
if (compression == OBJECT_COMPRESSED_XZ)
if (compression == COMPRESSION_XZ)
return decompress_blob_xz(
src, src_size,
dst, dst_size, dst_max);
else if (compression == OBJECT_COMPRESSED_LZ4)
else if (compression == COMPRESSION_LZ4)
return decompress_blob_lz4(
src, src_size,
dst, dst_size, dst_max);
else if (compression == OBJECT_COMPRESSED_ZSTD)
else if (compression == COMPRESSION_ZSTD)
return decompress_blob_zstd(
src, src_size,
dst, dst_size, dst_max);
@ -520,7 +518,7 @@ int decompress_startswith_zstd(
}
int decompress_startswith(
int compression,
Compression compression,
const void *src,
uint64_t src_size,
void **buffer,
@ -528,20 +526,20 @@ int decompress_startswith(
size_t prefix_len,
uint8_t extra) {
if (compression == OBJECT_COMPRESSED_XZ)
if (compression == COMPRESSION_XZ)
return decompress_startswith_xz(
src, src_size,
buffer,
prefix, prefix_len,
extra);
else if (compression == OBJECT_COMPRESSED_LZ4)
else if (compression == COMPRESSION_LZ4)
return decompress_startswith_lz4(
src, src_size,
buffer,
prefix, prefix_len,
extra);
else if (compression == OBJECT_COMPRESSED_ZSTD)
else if (compression == COMPRESSION_ZSTD)
return decompress_startswith_zstd(
src, src_size,
buffer,
@ -619,7 +617,7 @@ int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncom
s.total_in, s.total_out,
(double) s.total_out / s.total_in * 100);
return OBJECT_COMPRESSED_XZ;
return COMPRESSION_XZ;
}
}
}
@ -710,7 +708,7 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_unco
total_in, total_out,
(double) total_out / total_in * 100);
return OBJECT_COMPRESSED_LZ4;
return COMPRESSION_LZ4;
#else
return -EPROTONOSUPPORT;
#endif
@ -954,7 +952,7 @@ int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_unc
log_debug("ZSTD compression finished (%" PRIu64 " -> %" PRIu64 " bytes)",
in_bytes, max_bytes - left);
return OBJECT_COMPRESSED_ZSTD;
return COMPRESSION_ZSTD;
#else
return -EPROTONOSUPPORT;
#endif

View File

@ -3,10 +3,17 @@
#include <unistd.h>
#include "journal-def.h"
typedef enum Compression {
COMPRESSION_NONE,
COMPRESSION_XZ,
COMPRESSION_LZ4,
COMPRESSION_ZSTD,
_COMPRESSION_MAX,
_COMPRESSION_INVALID = -EINVAL,
} Compression;
const char* object_compressed_to_string(int compression);
int object_compressed_from_string(const char *compression);
const char* compression_to_string(Compression compression);
Compression compression_from_string(const char *compression);
int compress_blob_xz(const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size);
@ -21,7 +28,7 @@ int decompress_blob_lz4(const void *src, uint64_t src_size,
void **dst, size_t* dst_size, size_t dst_max);
int decompress_blob_zstd(const void *src, uint64_t src_size,
void **dst, size_t* dst_size, size_t dst_max);
int decompress_blob(int compression,
int decompress_blob(Compression compression,
const void *src, uint64_t src_size,
void **dst, size_t* dst_size, size_t dst_max);
@ -37,7 +44,7 @@ int decompress_startswith_zstd(const void *src, uint64_t src_size,
void **buffer,
const void *prefix, size_t prefix_len,
uint8_t extra);
int decompress_startswith(int compression,
int decompress_startswith(Compression compression,
const void *src, uint64_t src_size,
void **buffer,
const void *prefix, size_t prefix_len,
@ -51,27 +58,36 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);
static inline int compress_blob(const void *src, uint64_t src_size,
static inline int compress_blob_explicit(
Compression compression,
const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
switch (DEFAULT_COMPRESSION) {
case OBJECT_COMPRESSED_ZSTD:
switch (compression) {
case COMPRESSION_ZSTD:
return compress_blob_zstd(src, src_size, dst, dst_alloc_size, dst_size);
case OBJECT_COMPRESSED_LZ4:
case COMPRESSION_LZ4:
return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
case OBJECT_COMPRESSED_XZ:
case COMPRESSION_XZ:
return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
default:
return -EOPNOTSUPP;
}
}
#define compress_blob(src, src_size, dst, dst_alloc_size, dst_size) \
compress_blob_explicit( \
DEFAULT_COMPRESSION, \
src, src_size, \
dst, dst_alloc_size, dst_size)
static inline int compress_stream(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
switch (DEFAULT_COMPRESSION) {
case OBJECT_COMPRESSED_ZSTD:
case COMPRESSION_ZSTD:
return compress_stream_zstd(fdf, fdt, max_bytes, ret_uncompressed_size);
case OBJECT_COMPRESSED_LZ4:
case COMPRESSION_LZ4:
return compress_stream_lz4(fdf, fdt, max_bytes, ret_uncompressed_size);
case OBJECT_COMPRESSED_XZ:
case COMPRESSION_XZ:
return compress_stream_xz(fdf, fdt, max_bytes, ret_uncompressed_size);
default:
return -EOPNOTSUPP;
@ -80,11 +96,11 @@ static inline int compress_stream(int fdf, int fdt, uint64_t max_bytes, uint64_t
static inline const char* default_compression_extension(void) {
switch (DEFAULT_COMPRESSION) {
case OBJECT_COMPRESSED_ZSTD:
case COMPRESSION_ZSTD:
return ".zst";
case OBJECT_COMPRESSED_LZ4:
case COMPRESSION_LZ4:
return ".lz4";
case OBJECT_COMPRESSED_XZ:
case COMPRESSION_XZ:
return ".xz";
default:
return "";

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <fnmatch.h>
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
@ -2070,3 +2071,27 @@ bool set_equal(Set *a, Set *b) {
return true;
}
static bool set_fnmatch_one(Set *patterns, const char *needle) {
const char *p;
assert(needle);
SET_FOREACH(p, patterns)
if (fnmatch(p, needle, 0) == 0)
return true;
return false;
}
bool set_fnmatch(Set *include_patterns, Set *exclude_patterns, const char *needle) {
assert(needle);
if (set_fnmatch_one(exclude_patterns, needle))
return false;
if (set_isempty(include_patterns))
return true;
return set_fnmatch_one(include_patterns, needle);
}

View File

@ -446,3 +446,21 @@ libbasic_gcrypt = static_library(
dependencies : [libgcrypt],
c_args : ['-fvisibility=default'],
build_by_default : false)
############################################################
basic_compress_sources = files(
'compress.c',
'compress.h')
# A convenience library that is separate from libbasic to avoid unnecessary
# linking to the compression libraries.
libbasic_compress = static_library(
'basic-compress',
basic_compress_sources,
include_directories : basic_includes,
dependencies : [libxz,
libzstd,
liblz4],
c_args : ['-fvisibility=default'],
build_by_default : false)

View File

@ -153,3 +153,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
int set_strjoin(Set *s, const char *separator, bool wrap_with_separator, char **ret);
bool set_equal(Set *a, Set *b);
bool set_fnmatch(Set *include_patterns, Set *exclude_patterns, const char *needle);

View File

@ -6,21 +6,10 @@
#include "compress.h"
#include "fuzz.h"
static int compress(int alg,
const void *src, uint64_t src_size,
void *dst, size_t dst_alloc_size, size_t *dst_size) {
if (alg == OBJECT_COMPRESSED_LZ4)
return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
if (alg == OBJECT_COMPRESSED_XZ)
return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
return -EOPNOTSUPP;
}
typedef struct header {
uint32_t alg:2; /* We have only two compression algorithms so far, but we might add
* more in the future. Let's make this a bit wider so our fuzzer
* cases remain stable in the future. */
uint32_t alg:2; /* We have only three compression algorithms so far, but we might add more in the
* future. Let's make this a bit wider so our fuzzer cases remain stable in the
* future. */
uint32_t sw_len;
uint32_t sw_alloc;
uint32_t reserved[3]; /* Extra space to keep fuzz cases stable in case we need to
@ -46,7 +35,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
log_set_max_level(LOG_CRIT);
log_info("Using compression %s, data size=%zu",
object_compressed_to_string(alg) ?: "(none)",
compression_to_string(alg),
data_len);
buf = malloc(MAX(size, 128u)); /* Make the buffer a bit larger for very small data */
@ -56,7 +45,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
size_t csize;
r = compress(alg, h->data, data_len, buf, size, &csize);
r = compress_blob_explicit(alg, h->data, data_len, buf, size, &csize);
if (r < 0) {
log_error_errno(r, "Compression failed: %m");
return 0;

View File

@ -203,7 +203,7 @@ static bool check_compressed(uint64_t compress_threshold, uint64_t data_size) {
p = p + ALIGN64(le64toh(o->object.size));
}
is_compressed = (o->object.flags & OBJECT_COMPRESSION_MASK) != 0;
is_compressed = COMPRESSION_FROM_OBJECT(o) != COMPRESSION_NONE;
(void) managed_journal_file_close(f);

View File

@ -776,4 +776,5 @@ global:
sd_device_new_from_devname;
sd_device_new_from_path;
sd_device_open;
sd_device_enumerator_add_nomatch_sysname;
} LIBSYSTEMD_250;

View File

@ -5,8 +5,6 @@ sd_journal_sources = files(
'sd-journal/audit-type.h',
'sd-journal/catalog.c',
'sd-journal/catalog.h',
'sd-journal/compress.c',
'sd-journal/compress.h',
'sd-journal/journal-def.h',
'sd-journal/journal-file.c',
'sd-journal/journal-file.h',
@ -171,7 +169,8 @@ libsystemd_static = static_library(
libsystemd_sources,
include_directories : libsystemd_includes,
c_args : libsystemd_c_args,
link_with : libbasic,
link_with : [libbasic,
libbasic_compress],
dependencies : [threads,
librt],
build_by_default : false)
@ -206,19 +205,6 @@ tests += [
[files('sd-journal/test-catalog.c')],
[files('sd-journal/test-compress.c'),
[],
[liblz4,
libzstd,
libxz]],
[files('sd-journal/test-compress-benchmark.c'),
[],
[liblz4,
libzstd,
libxz],
[], '', 'timeout=90'],
[files('sd-journal/test-audit-type.c')],
]

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include "sd-device.h"
typedef enum MatchInitializedType {

View File

@ -42,6 +42,7 @@ struct sd_device_enumerator {
Hashmap *nomatch_sysattr;
Hashmap *match_property;
Set *match_sysname;
Set *nomatch_sysname;
Set *match_tag;
Set *match_parent;
MatchInitializedType match_initialized;
@ -96,6 +97,7 @@ static sd_device_enumerator *device_enumerator_free(sd_device_enumerator *enumer
hashmap_free(enumerator->nomatch_sysattr);
hashmap_free(enumerator->match_property);
set_free(enumerator->match_sysname);
set_free(enumerator->nomatch_sysname);
set_free(enumerator->match_tag);
set_free(enumerator->match_parent);
@ -183,13 +185,13 @@ _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enume
return 1;
}
_public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
static int device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname, bool match) {
int r;
assert_return(enumerator, -EINVAL);
assert_return(sysname, -EINVAL);
r = set_put_strdup(&enumerator->match_sysname, sysname);
r = set_put_strdup(match ? &enumerator->match_sysname : &enumerator->nomatch_sysname, sysname);
if (r <= 0)
return r;
@ -198,6 +200,14 @@ _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumer
return 1;
}
_public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
return device_enumerator_add_match_sysname(enumerator, sysname, true);
}
_public_ int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator, const char *sysname) {
return device_enumerator_add_match_sysname(enumerator, sysname, false);
}
_public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
int r;
@ -500,19 +510,10 @@ static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
}
static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
const char *sysname_match;
assert(enumerator);
assert(sysname);
if (set_isempty(enumerator->match_sysname))
return true;
SET_FOREACH(sysname_match, enumerator->match_sysname)
if (fnmatch(sysname_match, sysname, 0) == 0)
return true;
return false;
return set_fnmatch(enumerator->match_sysname, enumerator->nomatch_sysname, sysname);
}
static int match_initialized(sd_device_enumerator *enumerator, sd_device *device) {
@ -580,25 +581,12 @@ static int test_matches(
}
static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
const char *subsystem_match;
assert(enumerator);
if (!subsystem)
return false;
SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem)
if (fnmatch(subsystem_match, subsystem, 0) == 0)
return false;
if (set_isempty(enumerator->match_subsystem))
return true;
SET_FOREACH(subsystem_match, enumerator->match_subsystem)
if (fnmatch(subsystem_match, subsystem, 0) == 0)
return true;
return false;
return set_fnmatch(enumerator->match_subsystem, enumerator->nomatch_subsystem, subsystem);
}
static int enumerator_add_parent_devices(

View File

@ -182,6 +182,10 @@ TEST(sd_device_enumerator_devices) {
assert_se(sd_device_enumerator_new(&e) >= 0);
assert_se(sd_device_enumerator_allow_uninitialized(e) >= 0);
/* On some CI environments, it seems some loop block devices and corresponding bdi devices sometimes
* disappear during running this test. Let's exclude them here for stability. */
assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0);
assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0);
FOREACH_DEVICE(e, d)
test_sd_device_one(d);
}
@ -208,6 +212,8 @@ static void test_sd_device_enumerator_filter_subsystem_one(
assert_se(sd_device_enumerator_new(&e) >= 0);
assert_se(sd_device_enumerator_add_match_subsystem(e, subsystem, true) >= 0);
if (streq(subsystem, "block"))
assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0);
FOREACH_DEVICE(e, d) {
const char *syspath;
@ -250,6 +256,9 @@ TEST(sd_device_enumerator_filter_subsystem) {
assert_se(subsystems = hashmap_new(&string_hash_ops));
assert_se(sd_device_enumerator_new(&e) >= 0);
/* See comments in TEST(sd_device_enumerator_devices). */
assert_se(sd_device_enumerator_add_match_subsystem(e, "bdi", false) >= 0);
assert_se(sd_device_enumerator_add_nomatch_sysname(e, "loop*") >= 0);
FOREACH_DEVICE(e, d) {
const char *syspath, *subsystem;

View File

@ -42,14 +42,12 @@ typedef enum ObjectType {
_OBJECT_TYPE_MAX
} ObjectType;
/* Object flags
* The per-compression enums are also redefined in meson.build so that config.h is self-contained */
/* Object flags (note that src/basic/compress.h uses the same values for the compression types) */
enum {
OBJECT_COMPRESSED_XZ = 1 << 0,
OBJECT_COMPRESSED_LZ4 = 1 << 1,
OBJECT_COMPRESSED_ZSTD = 1 << 2,
OBJECT_COMPRESSION_MASK = OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD,
_OBJECT_COMPRESSED_MAX = OBJECT_COMPRESSION_MASK,
_OBJECT_COMPRESSED_MASK = OBJECT_COMPRESSED_XZ | OBJECT_COMPRESSED_LZ4 | OBJECT_COMPRESSED_ZSTD,
};
struct ObjectHeader {

View File

@ -1372,6 +1372,7 @@ int journal_file_find_data_object_with_hash(
p = le64toh(f->data_hash_table[h].head_hash_offset);
while (p > 0) {
Compression c;
Object *o;
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
@ -1381,7 +1382,10 @@ int journal_file_find_data_object_with_hash(
if (le64toh(o->data.hash) != hash)
goto next;
if (o->object.flags & OBJECT_COMPRESSION_MASK) {
c = COMPRESSION_FROM_OBJECT(o);
if (c < 0)
return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
uint64_t l;
size_t rsize = 0;
@ -1392,8 +1396,7 @@ int journal_file_find_data_object_with_hash(
l -= offsetof(Object, data.payload);
r = decompress_blob(o->object.flags & OBJECT_COMPRESSION_MASK,
o->data.payload, l, &f->compress_buffer, &rsize, 0);
r = decompress_blob(c, o->data.payload, l, &f->compress_buffer, &rsize, 0);
if (r < 0)
return r;
@ -1584,16 +1587,15 @@ static int journal_file_append_data(
size_t rsize = 0;
compression = compress_blob(data, size, o->data.payload, size - 1, &rsize);
if (compression >= 0) {
if (compression > COMPRESSION_NONE) {
o->object.size = htole64(offsetof(Object, data.payload) + rsize);
o->object.flags |= compression;
o->object.flags |= COMPRESSION_TO_MASK(compression);
log_debug("Compressed data object %"PRIu64" -> %zu using %s",
size, rsize, object_compressed_to_string(compression));
size, rsize, compression_to_string(compression));
} else
/* Compression didn't work, we don't really care why, let's continue without compression */
compression = 0;
compression = COMPRESSION_NONE;
}
#endif
@ -3143,6 +3145,7 @@ void journal_file_dump(JournalFile *f) {
p = le64toh(READ_NOW(f->header->header_size));
while (p != 0) {
const char *s;
Compression c;
r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
if (r < 0)
@ -3180,9 +3183,10 @@ void journal_file_dump(JournalFile *f) {
break;
}
if (o->object.flags & OBJECT_COMPRESSION_MASK)
c = COMPRESSION_FROM_OBJECT(o);
if (c > COMPRESSION_NONE)
printf("Flags: %s\n",
object_compressed_to_string(o->object.flags & OBJECT_COMPRESSION_MASK));
compression_to_string(c));
if (p == le64toh(f->header->tail_object_offset))
p = 0;
@ -3367,11 +3371,11 @@ int journal_file_open(
#endif
};
if (DEFAULT_COMPRESSION == OBJECT_COMPRESSED_ZSTD)
if (DEFAULT_COMPRESSION == COMPRESSION_ZSTD)
f->compress_zstd = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
else if (DEFAULT_COMPRESSION == OBJECT_COMPRESSED_LZ4)
else if (DEFAULT_COMPRESSION == COMPRESSION_LZ4)
f->compress_lz4 = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
else if (DEFAULT_COMPRESSION == OBJECT_COMPRESSED_XZ)
else if (DEFAULT_COMPRESSION == COMPRESSION_XZ)
f->compress_xz = FLAGS_SET(file_flags, JOURNAL_COMPRESS);
/* We turn on keyed hashes by default, but provide an environment variable to turn them off, if
@ -3689,6 +3693,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
items = newa(EntryItem, n);
for (uint64_t i = 0; i < n; i++) {
Compression c;
uint64_t l, h;
size_t t;
void *data;
@ -3711,12 +3716,15 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
if ((uint64_t) t != l)
return -E2BIG;
if (o->object.flags & OBJECT_COMPRESSION_MASK) {
c = COMPRESSION_FROM_OBJECT(o);
if (c < 0)
return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
size_t rsize = 0;
r = decompress_blob(
o->object.flags & OBJECT_COMPRESSION_MASK,
c,
o->data.payload, l,
&from->compress_buffer, &rsize,
0);

View File

@ -11,6 +11,7 @@
#include "sd-event.h"
#include "sd-id128.h"
#include "compress.h"
#include "hashmap.h"
#include "journal-def.h"
#include "mmap-cache.h"
@ -265,3 +266,33 @@ uint64_t journal_file_hash_data(JournalFile *f, const void *data, size_t sz);
bool journal_field_valid(const char *p, size_t l, bool allow_protected);
const char* journal_object_type_to_string(ObjectType type) _const_;
static inline Compression COMPRESSION_FROM_OBJECT(const Object *o) {
assert(o);
switch (o->object.flags & _OBJECT_COMPRESSED_MASK) {
case 0:
return COMPRESSION_NONE;
case OBJECT_COMPRESSED_XZ:
return COMPRESSION_XZ;
case OBJECT_COMPRESSED_LZ4:
return COMPRESSION_LZ4;
case OBJECT_COMPRESSED_ZSTD:
return COMPRESSION_ZSTD;
default:
return _COMPRESSION_INVALID;
}
}
static inline uint8_t COMPRESSION_TO_MASK(Compression c) {
switch (c) {
case COMPRESSION_XZ:
return OBJECT_COMPRESSED_XZ;
case COMPRESSION_LZ4:
return OBJECT_COMPRESSED_LZ4;
case COMPRESSION_ZSTD:
return OBJECT_COMPRESSED_ZSTD;
default:
return 0;
}
}

View File

@ -111,21 +111,24 @@ static void flush_progress(void) {
} while (0)
static int hash_payload(JournalFile *f, Object *o, uint64_t offset, const uint8_t *src, uint64_t size, uint64_t *res_hash) {
int compression, r;
Compression c;
int r;
assert(o);
assert(src);
assert(res_hash);
compression = o->object.flags & OBJECT_COMPRESSION_MASK;
if (compression) {
c = COMPRESSION_FROM_OBJECT(o);
if (c < 0)
return -EBADMSG;
if (c != COMPRESSION_NONE) {
_cleanup_free_ void *b = NULL;
size_t b_size;
r = decompress_blob(compression, src, size, &b, &b_size, 0);
r = decompress_blob(c, src, size, &b, &b_size, 0);
if (r < 0) {
error_errno(offset, r, "%s decompression failed: %m",
object_compressed_to_string(compression));
compression_to_string(c));
return r;
}
@ -145,7 +148,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
* possible field values. It does not follow any references to
* other objects. */
if ((o->object.flags & OBJECT_COMPRESSED_XZ) &&
if ((o->object.flags & _OBJECT_COMPRESSED_MASK) != 0 &&
o->object.type != OBJECT_DATA) {
error(offset,
"Found compressed object of type %s that isn't of type data, which is not allowed.",

View File

@ -2298,7 +2298,7 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
Object *d;
uint64_t p, l;
size_t t;
int compression;
Compression c;
p = le64toh(o->entry.items[i].object_offset);
r = journal_file_move_to_object(f, OBJECT_DATA, p, &d);
@ -2311,21 +2311,25 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
l = le64toh(d->object.size) - offsetof(Object, data.payload);
compression = d->object.flags & OBJECT_COMPRESSION_MASK;
if (compression) {
c = COMPRESSION_FROM_OBJECT(d);
if (c < 0)
return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
r = decompress_startswith(compression,
r = decompress_startswith(
c,
d->data.payload, l,
&f->compress_buffer,
field, field_length, '=');
if (r < 0)
log_debug_errno(r, "Cannot decompress %s object of length %"PRIu64" at offset "OFSfmt": %m",
object_compressed_to_string(compression), l, p);
compression_to_string(c), l, p);
else if (r > 0) {
size_t rsize;
r = decompress_blob(compression,
r = decompress_blob(
c,
d->data.payload, l,
&f->compress_buffer, &rsize,
j->data_threshold);
@ -2366,9 +2370,9 @@ static int return_data(
const void **ret_data,
size_t *ret_size) {
size_t t;
Compression c;
uint64_t l;
int compression;
size_t t;
assert(j);
assert(f);
@ -2383,14 +2387,16 @@ static int return_data(
if ((uint64_t) t != l)
return -E2BIG;
compression = o->object.flags & OBJECT_COMPRESSION_MASK;
if (compression) {
c = COMPRESSION_FROM_OBJECT(o);
if (c < 0)
return -EPROTONOSUPPORT;
if (c != COMPRESSION_NONE) {
#if HAVE_COMPRESSION
size_t rsize;
int r;
r = decompress_blob(
compression,
c,
o->data.payload, l,
&f->compress_buffer, &rsize,
j->data_threshold);

View File

@ -126,6 +126,7 @@ int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator, c
int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumerator, const char *sysattr, const char *value, int match);
int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator, const char *property, const char *value);
int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname);
int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator, const char *sysname);
int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag);
int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent);
int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator);

View File

@ -172,6 +172,16 @@ tests += [
[files('test-recurse-dir.c')],
[files('test-compress.c'),
[libshared,
libbasic_compress]],
[files('test-compress-benchmark.c'),
[libshared,
libbasic_compress],
[],
[], '', 'timeout=90'],
[files('test-data-fd-util.c')],
[files('test-static-destruct.c')],

View File

@ -293,10 +293,10 @@ int main(int argc, char *argv[]) {
random_bytes(data + 7, sizeof(data) - 7);
#if HAVE_XZ
test_compress_decompress(OBJECT_COMPRESSED_XZ, "XZ",
test_compress_decompress(COMPRESSION_XZ, "XZ",
compress_blob_xz, decompress_blob_xz,
text, sizeof(text), false);
test_compress_decompress(OBJECT_COMPRESSED_XZ, "XZ",
test_compress_decompress(COMPRESSION_XZ, "XZ",
compress_blob_xz, decompress_blob_xz,
data, sizeof(data), true);
@ -310,7 +310,7 @@ int main(int argc, char *argv[]) {
compress_blob_xz, decompress_startswith_xz,
huge, HUGE_SIZE, true);
test_compress_stream(OBJECT_COMPRESSED_XZ, "XZ", "xzcat",
test_compress_stream(COMPRESSION_XZ, "XZ", "xzcat",
compress_stream_xz, decompress_stream_xz, srcfile);
test_decompress_startswith_short("XZ", compress_blob_xz, decompress_startswith_xz);
@ -320,10 +320,10 @@ int main(int argc, char *argv[]) {
#endif
#if HAVE_LZ4
test_compress_decompress(OBJECT_COMPRESSED_LZ4, "LZ4",
test_compress_decompress(COMPRESSION_LZ4, "LZ4",
compress_blob_lz4, decompress_blob_lz4,
text, sizeof(text), false);
test_compress_decompress(OBJECT_COMPRESSED_LZ4, "LZ4",
test_compress_decompress(COMPRESSION_LZ4, "LZ4",
compress_blob_lz4, decompress_blob_lz4,
data, sizeof(data), true);
@ -337,7 +337,7 @@ int main(int argc, char *argv[]) {
compress_blob_lz4, decompress_startswith_lz4,
huge, HUGE_SIZE, true);
test_compress_stream(OBJECT_COMPRESSED_LZ4, "LZ4", "lz4cat",
test_compress_stream(COMPRESSION_LZ4, "LZ4", "lz4cat",
compress_stream_lz4, decompress_stream_lz4, srcfile);
test_lz4_decompress_partial();
@ -349,10 +349,10 @@ int main(int argc, char *argv[]) {
#endif
#if HAVE_ZSTD
test_compress_decompress(OBJECT_COMPRESSED_ZSTD, "ZSTD",
test_compress_decompress(COMPRESSION_ZSTD, "ZSTD",
compress_blob_zstd, decompress_blob_zstd,
text, sizeof(text), false);
test_compress_decompress(OBJECT_COMPRESSED_ZSTD, "ZSTD",
test_compress_decompress(COMPRESSION_ZSTD, "ZSTD",
compress_blob_zstd, decompress_blob_zstd,
data, sizeof(data), true);
@ -366,7 +366,7 @@ int main(int argc, char *argv[]) {
compress_blob_zstd, decompress_startswith_zstd,
huge, HUGE_SIZE, true);
test_compress_stream(OBJECT_COMPRESSED_ZSTD, "ZSTD", "zstdcat",
test_compress_stream(COMPRESSION_ZSTD, "ZSTD", "zstdcat",
compress_stream_zstd, decompress_stream_zstd, srcfile);
test_decompress_startswith_short("ZSTD", compress_blob_zstd, decompress_startswith_zstd);

View File

@ -330,4 +330,50 @@ TEST(set_equal) {
assert_se(set_equal(b, a));
}
TEST(set_fnmatch) {
_cleanup_set_free_ Set *match = NULL, *nomatch = NULL;
assert_se(set_put_strdup(&match, "aaa") >= 0);
assert_se(set_put_strdup(&match, "bbb*") >= 0);
assert_se(set_put_strdup(&match, "*ccc") >= 0);
assert_se(set_put_strdup(&nomatch, "a*") >= 0);
assert_se(set_put_strdup(&nomatch, "bbb") >= 0);
assert_se(set_put_strdup(&nomatch, "ccc*") >= 0);
assert_se(set_fnmatch(NULL, NULL, ""));
assert_se(set_fnmatch(NULL, NULL, "hoge"));
assert_se(set_fnmatch(match, NULL, "aaa"));
assert_se(set_fnmatch(match, NULL, "bbb"));
assert_se(set_fnmatch(match, NULL, "bbbXXX"));
assert_se(set_fnmatch(match, NULL, "ccc"));
assert_se(set_fnmatch(match, NULL, "XXXccc"));
assert_se(!set_fnmatch(match, NULL, ""));
assert_se(!set_fnmatch(match, NULL, "aaaa"));
assert_se(!set_fnmatch(match, NULL, "XXbbb"));
assert_se(!set_fnmatch(match, NULL, "cccXX"));
assert_se(set_fnmatch(NULL, nomatch, ""));
assert_se(set_fnmatch(NULL, nomatch, "Xa"));
assert_se(set_fnmatch(NULL, nomatch, "bbbb"));
assert_se(set_fnmatch(NULL, nomatch, "XXXccc"));
assert_se(!set_fnmatch(NULL, nomatch, "a"));
assert_se(!set_fnmatch(NULL, nomatch, "aXXXX"));
assert_se(!set_fnmatch(NULL, nomatch, "bbb"));
assert_se(!set_fnmatch(NULL, nomatch, "ccc"));
assert_se(!set_fnmatch(NULL, nomatch, "cccXXX"));
assert_se(set_fnmatch(match, nomatch, "bbbbb"));
assert_se(set_fnmatch(match, nomatch, "XXccc"));
assert_se(!set_fnmatch(match, nomatch, ""));
assert_se(!set_fnmatch(match, nomatch, "a"));
assert_se(!set_fnmatch(match, nomatch, "aaa"));
assert_se(!set_fnmatch(match, nomatch, "b"));
assert_se(!set_fnmatch(match, nomatch, "bbb"));
assert_se(!set_fnmatch(match, nomatch, "ccc"));
assert_se(!set_fnmatch(match, nomatch, "ccccc"));
assert_se(!set_fnmatch(match, nomatch, "cccXX"));
}
DEFINE_TEST_MAIN(LOG_INFO);

View File

@ -122,8 +122,7 @@ int main(int argc, char **argv) {
test_table(unit_load_state, UNIT_LOAD_STATE);
test_table(unit_type, UNIT_TYPE);
test_table(virtualization, VIRTUALIZATION);
test_table_sparse(object_compressed, OBJECT_COMPRESSED);
test_table(compression, COMPRESSION);
assert_cc(sizeof(sd_device_action_t) == sizeof(int64_t));