From 11e6d9714ebcae00cb42a0d0910881b2b6570742 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Tue, 25 Jun 2019 15:54:44 +0200 Subject: [PATCH] journal-import: extract helpers for handling arrays of iovec and make them available for others --- src/basic/io-util.c | 53 +++++++++++++++++++++++ src/basic/io-util.h | 14 ++++++ src/coredump/coredump.c | 4 +- src/journal-remote/journal-remote-parse.c | 2 +- src/shared/journal-importer.c | 35 +-------------- src/shared/journal-importer.h | 13 ++---- src/test/test-journal-importer.c | 4 +- 7 files changed, 77 insertions(+), 48 deletions(-) diff --git a/src/basic/io-util.c b/src/basic/io-util.c index 9394e54bc5..38de26a72c 100644 --- a/src/basic/io-util.c +++ b/src/basic/io-util.c @@ -270,3 +270,56 @@ char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const ch free(value); return x; } + +struct iovec_wrapper *iovw_new(void) { + return malloc0(sizeof(struct iovec_wrapper)); +} + +void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors) { + if (free_vectors) + for (size_t i = 0; i < iovw->count; i++) + free(iovw->iovec[i].iov_base); + + iovw->iovec = mfree(iovw->iovec); + iovw->count = 0; + iovw->size_bytes = 0; +} + +struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw) { + iovw_free_contents(iovw, true); + + return mfree(iovw); +} + +struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw) { + iovw_free_contents(iovw, false); + + return mfree(iovw); +} + +int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) { + if (iovw->count >= IOV_MAX) + return -E2BIG; + + if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1)) + return log_oom(); + + iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len); + return 0; +} + +void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) { + size_t i; + + for (i = 0; i < iovw->count; i++) + iovw->iovec[i].iov_base = (char *)iovw->iovec[i].iov_base - old + new; +} + +size_t iovw_size(struct iovec_wrapper *iovw) { + size_t n = 0, i; + + for (i = 0; i < iovw->count; i++) + n += iovw->iovec[i].iov_len; + + return n; +} diff --git a/src/basic/io-util.h b/src/basic/io-util.h index d1fb7e78d2..e689fe1f43 100644 --- a/src/basic/io-util.h +++ b/src/basic/io-util.h @@ -74,3 +74,17 @@ static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value); + +struct iovec_wrapper { + struct iovec *iovec; + size_t count; + size_t size_bytes; +}; + +struct iovec_wrapper *iovw_new(void); +struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw); +struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw); +void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors); +int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); +void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new); +size_t iovw_size(struct iovec_wrapper *iovw); diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 1a5a2dc81d..e991fe4af0 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -1237,9 +1237,7 @@ static int process_backtrace(int argc, char *argv[]) { _cleanup_free_ struct iovec *iovec = NULL; size_t n_iovec, n_allocated, n_to_free = 0, i; int r; - _cleanup_(journal_importer_cleanup) JournalImporter importer = { - .fd = STDIN_FILENO, - }; + _cleanup_(journal_importer_cleanup) JournalImporter importer = JOURNAL_IMPORTER_INIT(STDIN_FILENO); log_debug("Processing backtrace on stdin..."); diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c index ebcae2fcaa..dc047b2d49 100644 --- a/src/journal-remote/journal-remote-parse.c +++ b/src/journal-remote/journal-remote-parse.c @@ -38,7 +38,7 @@ RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) { if (!source) return NULL; - source->importer.fd = fd; + source->importer = JOURNAL_IMPORTER_MAKE(fd); source->importer.passive_fd = passive_fd; source->importer.name = name; diff --git a/src/shared/journal-importer.c b/src/shared/journal-importer.c index 8dc2c42ad1..218fbe9057 100644 --- a/src/shared/journal-importer.c +++ b/src/shared/journal-importer.c @@ -22,37 +22,6 @@ enum { IMPORTER_STATE_EOF, /* done */ }; -static int iovw_put(struct iovec_wrapper *iovw, void* data, size_t len) { - if (iovw->count >= ENTRY_FIELD_COUNT_MAX) - return -E2BIG; - - if (!GREEDY_REALLOC(iovw->iovec, iovw->size_bytes, iovw->count + 1)) - return log_oom(); - - iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len); - return 0; -} - -static void iovw_free_contents(struct iovec_wrapper *iovw) { - iovw->iovec = mfree(iovw->iovec); - iovw->size_bytes = iovw->count = 0; -} - -static void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) { - size_t i; - - for (i = 0; i < iovw->count; i++) - iovw->iovec[i].iov_base = (char*) iovw->iovec[i].iov_base - old + new; -} - -size_t iovw_size(struct iovec_wrapper *iovw) { - size_t n = 0, i; - - for (i = 0; i < iovw->count; i++) - n += iovw->iovec[i].iov_len; - - return n; -} void journal_importer_cleanup(JournalImporter *imp) { if (imp->fd >= 0 && !imp->passive_fd) { @@ -62,7 +31,7 @@ void journal_importer_cleanup(JournalImporter *imp) { free(imp->name); free(imp->buf); - iovw_free_contents(&imp->iovw); + iovw_free_contents(&imp->iovw, false); } static char* realloc_buffer(JournalImporter *imp, size_t size) { @@ -466,7 +435,7 @@ void journal_importer_drop_iovw(JournalImporter *imp) { /* This function drops processed data that along with the iovw that points at it */ - iovw_free_contents(&imp->iovw); + iovw_free_contents(&imp->iovw, false); /* possibly reset buffer position */ remain = imp->filled - imp->offset; diff --git a/src/shared/journal-importer.h b/src/shared/journal-importer.h index 7914c0cf5f..b2e3c817f5 100644 --- a/src/shared/journal-importer.h +++ b/src/shared/journal-importer.h @@ -6,8 +6,8 @@ #include #include +#include "io-util.h" #include "sd-id128.h" - #include "time-util.h" /* Make sure not to make this smaller than the maximum coredump size. @@ -24,14 +24,6 @@ /* The maximum number of fields in an entry */ #define ENTRY_FIELD_COUNT_MAX 1024 -struct iovec_wrapper { - struct iovec *iovec; - size_t size_bytes; - size_t count; -}; - -size_t iovw_size(struct iovec_wrapper *iovw); - typedef struct JournalImporter { int fd; bool passive_fd; @@ -53,6 +45,9 @@ typedef struct JournalImporter { sd_id128_t boot_id; } JournalImporter; +#define JOURNAL_IMPORTER_INIT(_fd) { .fd = (_fd), .iovw = {} } +#define JOURNAL_IMPORTER_MAKE(_fd) (JournalImporter) JOURNAL_IMPORTER_INIT(_fd) + void journal_importer_cleanup(JournalImporter *); int journal_importer_process_data(JournalImporter *); int journal_importer_push_data(JournalImporter *, const char *data, size_t size); diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c index cddbfa7022..7e898735c9 100644 --- a/src/test/test-journal-importer.c +++ b/src/test/test-journal-importer.c @@ -21,7 +21,7 @@ static void assert_iovec_entry(const struct iovec *iovec, const char* content) { "0::/user.slice/user-1002.slice/user@1002.service/gnome-terminal-server.service\n" static void test_basic_parsing(void) { - _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; + _cleanup_(journal_importer_cleanup) JournalImporter imp = JOURNAL_IMPORTER_INIT(-1); _cleanup_free_ char *journal_data_path = NULL; int r; @@ -52,7 +52,7 @@ static void test_basic_parsing(void) { } static void test_bad_input(void) { - _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; + _cleanup_(journal_importer_cleanup) JournalImporter imp = JOURNAL_IMPORTER_INIT(-1); _cleanup_free_ char *journal_data_path = NULL; int r;