]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
compress: return uncompressed size to the caller
authorLuca Boccassi <luca.boccassi@microsoft.com>
Fri, 12 Mar 2021 20:16:53 +0000 (20:16 +0000)
committerLuca Boccassi <luca.boccassi@microsoft.com>
Tue, 8 Jun 2021 13:05:56 +0000 (14:05 +0100)
Useful when compressing anonymous FDs that cannot be rewund

src/libsystemd/sd-journal/compress.c
src/libsystemd/sd-journal/compress.h
src/libsystemd/sd-journal/test-compress.c

index c788dd8caf9e9e00b7ced2434cac1e0a94c45005..837abab76c8139860fbd747b03397c775f962fc4 100644 (file)
@@ -550,7 +550,7 @@ int decompress_startswith(
                 return -EBADMSG;
 }
 
-int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
 #if HAVE_XZ
         _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
         lzma_ret ret;
@@ -611,6 +611,9 @@ int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
                                 return k;
 
                         if (ret == LZMA_STREAM_END) {
+                                if (ret_uncompressed_size)
+                                        *ret_uncompressed_size = s.total_in;
+
                                 log_debug("XZ compression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)",
                                           s.total_in, s.total_out,
                                           (double) s.total_out / s.total_in * 100);
@@ -626,14 +629,15 @@ int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
 
 #define LZ4_BUFSIZE (512*1024u)
 
-int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
 
 #if HAVE_LZ4
         LZ4F_errorCode_t c;
         _cleanup_(LZ4F_freeCompressionContextp) LZ4F_compressionContext_t ctx = NULL;
         _cleanup_free_ void *in_buff = NULL;
         _cleanup_free_ char *out_buff = NULL;
-        size_t out_allocsize, n, total_in = 0, total_out, offset = 0, frame_size;
+        size_t out_allocsize, n, offset = 0, frame_size;
+        uint64_t total_in = 0, total_out;
         int r;
         static const LZ4F_preferences_t preferences = {
                 .frameInfo.blockSizeID = 5,
@@ -698,7 +702,10 @@ int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
         if (r < 0)
                 return r;
 
-        log_debug("LZ4 compression finished (%zu -> %zu bytes, %.1f%%)",
+        if (ret_uncompressed_size)
+                *ret_uncompressed_size = total_in;
+
+        log_debug("LZ4 compression finished (%" PRIu64 " -> %" PRIu64 " bytes, %.1f%%)",
                   total_in, total_out,
                   (double) total_out / total_in * 100);
 
@@ -844,7 +851,7 @@ int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
 #endif
 }
 
-int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
+int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
 #if HAVE_ZSTD
         _cleanup_(ZSTD_freeCCtxp) ZSTD_CCtx *cctx = NULL;
         _cleanup_free_ void *in_buff = NULL, *out_buff = NULL;
@@ -933,6 +940,9 @@ int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
                         break;
         }
 
+        if (ret_uncompressed_size)
+                *ret_uncompressed_size = in_bytes;
+
         if (in_bytes > 0)
                 log_debug("ZSTD compression finished (%" PRIu64 " -> %" PRIu64 " bytes, %.1f%%)",
                           in_bytes, max_bytes - left, (double) (max_bytes - left) / in_bytes * 100);
index a82049edd8a8f94e30656f2791bd60d3b41b76db..005e60e2e3e4b02eb9d0aeee32a5c47694edfead 100644 (file)
@@ -64,9 +64,9 @@ int decompress_startswith(int compression,
                           const void *prefix, size_t prefix_len,
                           uint8_t extra);
 
-int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes);
-int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes);
-int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes);
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
+int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size);
 
 int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
 int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
@@ -82,7 +82,7 @@ int decompress_stream_zstd(int fdf, int fdt, uint64_t max_size);
 #  define compress_stream compress_stream_xz
 #  define COMPRESSED_EXT ".xz"
 #else
-static inline int compress_stream(int fdf, int fdt, uint64_t max_size) {
+static inline int compress_stream(int fdf, int fdt, uint64_t max_size, uint64_t *ret_uncompressed_size) {
         return -EOPNOTSUPP;
 }
 #  define COMPRESSED_EXT ""
index 0d5069d477281f34151ed8f791c15260bf11c016..54e0e738b3b645e0f13b3ab1496996de0767a4ca 100644 (file)
@@ -41,7 +41,7 @@ typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
                               const void *prefix, size_t prefix_len,
                               uint8_t extra);
 
-typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
+typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes, uint64_t *uncompressed_size);
 typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
 
 #if HAVE_COMPRESSION
@@ -176,6 +176,7 @@ _unused_ static void test_compress_stream(const char *compression,
         int r;
         _cleanup_free_ char *cmd = NULL, *cmd2 = NULL;
         struct stat st = {};
+        uint64_t uncompressed_size;
 
         r = find_executable(cat, NULL);
         if (r < 0) {
@@ -193,7 +194,7 @@ _unused_ static void test_compress_stream(const char *compression,
 
         assert_se((dst = mkostemp_safe(pattern)) >= 0);
 
-        assert_se(compress(src, dst, -1) == 0);
+        assert_se(compress(src, dst, -1, &uncompressed_size) == 0);
 
         if (cat) {
                 assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
@@ -205,6 +206,7 @@ _unused_ static void test_compress_stream(const char *compression,
         assert_se((dst2 = mkostemp_safe(pattern2)) >= 0);
 
         assert_se(stat(srcfile, &st) == 0);
+        assert_se((uint64_t)st.st_size == uncompressed_size);
 
         assert_se(lseek(dst, 0, SEEK_SET) == 0);
         r = decompress(dst, dst2, st.st_size);