From: Lennart Poettering Date: Fri, 22 Aug 2025 15:04:37 +0000 (+0200) Subject: import: always use the same buffer size X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F39008%2Fhead;p=thirdparty%2Fsystemd.git import: always use the same buffer size Let's synchronize the buffer sizes used when passing around the disk images, i.e. size both our internal buffers and the pipe buffers the same (so that we can always write()/read() everything in one gone - except for the noise compression inserts). Let's also increase the buffer sizes from 16K to 128K, which made a difference for me, because it reduces the number of syscalls quite a bit. --- diff --git a/src/import/export-raw.c b/src/import/export-raw.c index 787d230d2ff..767e10f3ce3 100644 --- a/src/import/export-raw.c +++ b/src/import/export-raw.c @@ -11,6 +11,7 @@ #include "fd-util.h" #include "format-util.h" #include "fs-util.h" +#include "import-common.h" #include "log.h" #include "pretty-print.h" #include "ratelimit.h" @@ -20,8 +21,6 @@ #include "time-util.h" #include "tmpfile-util.h" -#define COPY_BUFFER_SIZE (16*1024) - typedef struct RawExport { sd_event *event; @@ -161,7 +160,7 @@ static int raw_export_process(RawExport *e) { if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) { - l = sendfile(e->output_fd, e->input_fd, NULL, COPY_BUFFER_SIZE); + l = sendfile(e->output_fd, e->input_fd, NULL, IMPORT_BUFFER_SIZE); if (l < 0) { if (errno == EAGAIN) return 0; @@ -181,7 +180,7 @@ static int raw_export_process(RawExport *e) { } while (e->buffer_size <= 0) { - uint8_t input[COPY_BUFFER_SIZE]; + uint8_t input[IMPORT_BUFFER_SIZE]; if (e->eof) { r = 0; diff --git a/src/import/export-tar.c b/src/import/export-tar.c index 5b907769a07..58b4273c6dc 100644 --- a/src/import/export-tar.c +++ b/src/import/export-tar.c @@ -20,8 +20,6 @@ #include "time-util.h" #include "tmpfile-util.h" -#define COPY_BUFFER_SIZE (16*1024) - typedef struct TarExport { sd_event *event; @@ -181,7 +179,7 @@ static int tar_export_process(TarExport *e) { if (!e->tried_splice && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) { - l = splice(e->tar_fd, NULL, e->output_fd, NULL, COPY_BUFFER_SIZE, 0); + l = splice(e->tar_fd, NULL, e->output_fd, NULL, IMPORT_BUFFER_SIZE, 0); if (l < 0) { if (errno == EAGAIN) return 0; @@ -201,7 +199,7 @@ static int tar_export_process(TarExport *e) { } while (e->buffer_size <= 0) { - uint8_t input[COPY_BUFFER_SIZE]; + uint8_t input[IMPORT_BUFFER_SIZE]; if (e->eof) { r = tar_export_finish(e); diff --git a/src/import/import-common.c b/src/import/import-common.c index bab81d596f9..2de01953a39 100644 --- a/src/import/import-common.c +++ b/src/import/import-common.c @@ -32,6 +32,8 @@ int import_fork_tar_x(const char *path, pid_t *ret) { if (pipe2(pipefd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pipe for tar: %m"); + (void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE); + use_selinux = mac_selinux_use(); r = safe_fork_full("(tar)", @@ -101,6 +103,8 @@ int import_fork_tar_c(const char *path, pid_t *ret) { if (pipe2(pipefd, O_CLOEXEC) < 0) return log_error_errno(errno, "Failed to create pipe for tar: %m"); + (void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE); + use_selinux = mac_selinux_use(); r = safe_fork_full("(tar)", diff --git a/src/import/import-common.h b/src/import/import-common.h index bb7d5614f01..3b571a3f993 100644 --- a/src/import/import-common.h +++ b/src/import/import-common.h @@ -41,3 +41,5 @@ int import_mangle_os_tree(const char *path); bool import_validate_local(const char *name, ImportFlags flags); int import_allocate_event_with_signals(sd_event **ret); + +#define IMPORT_BUFFER_SIZE (128U*1024U) diff --git a/src/import/import-compress.c b/src/import/import-compress.c index 666a2c3aaba..f893abc43e6 100644 --- a/src/import/import-compress.c +++ b/src/import/import-compress.c @@ -3,6 +3,7 @@ #include #include +#include "import-common.h" #include "import-compress.h" #include "log.h" #include "string-table.h" @@ -148,7 +149,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo c->xz.avail_in = size; while (c->xz.avail_in > 0) { - uint8_t buffer[16 * 1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; lzma_ret lzr; c->xz.next_out = buffer; @@ -172,7 +173,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo c->gzip.avail_in = size; while (c->gzip.avail_in > 0) { - uint8_t buffer[16 * 1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; c->gzip.next_out = buffer; c->gzip.avail_out = sizeof(buffer); @@ -196,7 +197,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo c->bzip2.avail_in = size; while (c->bzip2.avail_in > 0) { - uint8_t buffer[16 * 1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; c->bzip2.next_out = (char*) buffer; c->bzip2.avail_out = sizeof(buffer); @@ -222,7 +223,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo }; while (input.pos < input.size) { - uint8_t buffer[16 * 1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; ZSTD_outBuffer output = { .dst = buffer, .size = sizeof(buffer), @@ -320,7 +321,7 @@ static int enlarge_buffer(void **buffer, size_t *buffer_size, size_t *buffer_all if (*buffer_allocated > *buffer_size) return 0; - l = MAX(16*1024U, (*buffer_size * 2)); + l = MAX(IMPORT_BUFFER_SIZE, (*buffer_size * 2)); p = realloc(*buffer, l); if (!p) return -ENOMEM; diff --git a/src/import/import-raw.c b/src/import/import-raw.c index dc1a4b1c623..1d7302cd882 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -47,7 +47,7 @@ typedef struct RawImport { sd_event_source *input_event_source; - uint8_t buffer[16*1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; size_t buffer_size; uint64_t written_compressed; diff --git a/src/import/import-tar.c b/src/import/import-tar.c index b4b9b8dc997..14ee1b4ab80 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -49,7 +49,7 @@ typedef struct TarImport { sd_event_source *input_event_source; - uint8_t buffer[16*1024]; + uint8_t buffer[IMPORT_BUFFER_SIZE]; size_t buffer_size; uint64_t written_compressed;