From 90ed413c5a90a417e239f0d853a8a10fb7bf072e Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 19 Jul 2023 18:29:12 -0700 Subject: [PATCH] libsysprof: add API to add compressed file from data --- src/libsysprof/sysprof-linux-instrument.c | 2 +- src/libsysprof/sysprof-recording-private.h | 3 +- src/libsysprof/sysprof-recording.c | 46 +++++++++++++++++++++- src/libsysprof/sysprof-symbols-bundle.c | 3 +- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/libsysprof/sysprof-linux-instrument.c b/src/libsysprof/sysprof-linux-instrument.c index 7dc7db0c..fc96133b 100644 --- a/src/libsysprof/sysprof-linux-instrument.c +++ b/src/libsysprof/sysprof-linux-instrument.c @@ -211,7 +211,7 @@ add_process_info (SysprofRecording *recording, * in resolving symbols later on. */ mount_path = g_strdup_printf ("/proc/%u/mountinfo", pid); - _sysprof_recording_add_file_data (recording, mount_path, mountinfo, -1); + _sysprof_recording_add_file_data (recording, mount_path, mountinfo, -1, FALSE); /* Ignore inodes from podman/toolbox because they appear to always be * wrong. We'll have to rely on CRC/build-id instead. diff --git a/src/libsysprof/sysprof-recording-private.h b/src/libsysprof/sysprof-recording-private.h index 8d36b718..4fbbbe44 100644 --- a/src/libsysprof/sysprof-recording-private.h +++ b/src/libsysprof/sysprof-recording-private.h @@ -41,7 +41,8 @@ DexFuture *_sysprof_recording_add_file (SysprofRecording *s void _sysprof_recording_add_file_data (SysprofRecording *self, const char *path, const char *contents, - gssize length); + gssize length, + gboolean compress); void _sysprof_recording_diagnostic (SysprofRecording *self, const char *domain, const char *format, diff --git a/src/libsysprof/sysprof-recording.c b/src/libsysprof/sysprof-recording.c index e99a64d6..590a8d67 100644 --- a/src/libsysprof/sysprof-recording.c +++ b/src/libsysprof/sysprof-recording.c @@ -712,12 +712,43 @@ _sysprof_recording_add_file (SysprofRecording *self, (GDestroyNotify)add_file_free); } +static char * +do_compress (const char *data, + gsize length, + gsize *out_length) +{ + g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, 6); + g_autofree char *compressed = g_malloc (length); + GConverterResult res; + gsize n_read; + gsize n_written; + + *out_length = 0; + + res = g_converter_convert (G_CONVERTER (compressor), data, length, compressed, length, + G_CONVERTER_INPUT_AT_END | G_CONVERTER_FLUSH, + &n_read, &n_written, NULL); + + if (res == G_CONVERTER_FINISHED) + { + *out_length = n_written; + return g_steal_pointer (&compressed); + } + + return NULL; +} + void _sysprof_recording_add_file_data (SysprofRecording *self, const char *path, const char *contents, - gssize length) + gssize length, + gboolean compress) { + g_autofree char *compress_filename = NULL; + g_autofree char *compress_bytes = NULL; + gsize compress_len = 0; + g_return_if_fail (SYSPROF_IS_RECORDING (self)); g_return_if_fail (path != NULL); g_return_if_fail (contents != NULL); @@ -725,6 +756,19 @@ _sysprof_recording_add_file_data (SysprofRecording *self, if (length < 0) length = strlen (contents); + if (compress) + { + compress_bytes = do_compress (contents, length, &compress_len); + + if (compress_bytes) + { + compress_filename = g_strdup_printf ("%s.gz", path); + path = compress_filename; + contents = compress_bytes; + length = compress_len; + } + } + while (length > 0) { gsize to_write = MIN (length, ((4096*8)-sizeof (SysprofCaptureFileChunk))); diff --git a/src/libsysprof/sysprof-symbols-bundle.c b/src/libsysprof/sysprof-symbols-bundle.c index 651e2197..ecb93603 100644 --- a/src/libsysprof/sysprof-symbols-bundle.c +++ b/src/libsysprof/sysprof-symbols-bundle.c @@ -91,7 +91,8 @@ sysprof_symbols_bundle_augment_fiber (gpointer user_data) _sysprof_recording_add_file_data (recording, "__symbols__", g_bytes_get_data (bytes, NULL), - g_bytes_get_size (bytes)); + g_bytes_get_size (bytes), + TRUE); return dex_future_new_for_boolean (TRUE); }