From 7d64aa48fcfc03a93ea1623338a760e66406b132 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 23 May 2017 21:45:31 -0600 Subject: [PATCH] log: make the logging functions handle > 1024 bytes correctly We simply truncate the output if it's larger than our static buffer. Make it dynamically allocated instead, and ensure that we loop correctly to handle the full amount asked for. This fixes a problem with truncated output. One example is json output, with file names (for multiple files) that are larger than 1024 bytes. With the truncated output, we would truncate the file name and hence also miss the terminating '"'. The latter means the json was no longer valid, either. Signed-off-by: Jens Axboe --- log.c | 111 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/log.c b/log.c index 172f1538..f34892dc 100644 --- a/log.c +++ b/log.c @@ -6,6 +6,8 @@ #include "fio.h" +#define LOG_START_SZ 512 + size_t log_info_buf(const char *buf, size_t len) { /* @@ -29,38 +31,76 @@ size_t log_info_buf(const char *buf, size_t len) size_t log_valist(const char *str, va_list args) { - char buffer[1024]; - size_t len; + size_t len, cur = LOG_START_SZ; + char *buffer; + + do { + buffer = calloc(1, cur); + + len = vsnprintf(buffer, cur, str, args); + if (len <= cur) + break; - len = vsnprintf(buffer, sizeof(buffer), str, args); + cur = len; + free(buffer); + } while (1); - return log_info_buf(buffer, min(len, sizeof(buffer) - 1)); + cur = log_info_buf(buffer, len); + free(buffer); + + return cur; } size_t log_info(const char *format, ...) { - char buffer[1024]; + size_t len, cur = LOG_START_SZ; + char *buffer; va_list args; - size_t len; - va_start(args, format); - len = vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); + do { + buffer = calloc(1, cur); + + va_start(args, format); + len = vsnprintf(buffer, cur, format, args); + va_end(args); - return log_info_buf(buffer, min(len, sizeof(buffer) - 1)); + if (len <= cur) + break; + + cur = len; + free(buffer); + } while (1); + + cur = log_info_buf(buffer, len); + free(buffer); + + return cur; } size_t __log_buf(struct buf_output *buf, const char *format, ...) { - char buffer[1024]; + size_t len, cur = LOG_START_SZ; + char *buffer; va_list args; - size_t len; - va_start(args, format); - len = vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); + do { + buffer = calloc(1, cur); + + va_start(args, format); + len = vsnprintf(buffer, cur, format, args); + va_end(args); + + if (len <= cur) + break; - return buf_output_add(buf, buffer, min(len, sizeof(buffer) - 1)); + cur = len; + free(buffer); + } while (1); + + cur = buf_output_add(buf, buffer, len); + free(buffer); + + return cur; } int log_info_flush(void) @@ -73,33 +113,44 @@ int log_info_flush(void) size_t log_err(const char *format, ...) { - char buffer[1024]; + size_t ret, len, cur = LOG_START_SZ; + char *buffer; va_list args; - size_t len; - va_start(args, format); - len = vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); - len = min(len, sizeof(buffer) - 1); + do { + buffer = calloc(1, cur); + + va_start(args, format); + len = vsnprintf(buffer, cur, format, args); + va_end(args); + + if (len <= cur) + break; + + cur = len; + free(buffer); + } while (1); + if (is_backend) { - size_t ret = fio_server_text_output(FIO_LOG_ERR, buffer, len); + ret = fio_server_text_output(FIO_LOG_ERR, buffer, len); if (ret != -1) - return ret; + goto done; } if (log_syslog) { syslog(LOG_INFO, "%s", buffer); - return len; + ret = len; } else { - if (f_err != stderr) { - int fio_unused ret; - + if (f_err != stderr) ret = fwrite(buffer, len, 1, stderr); - } - return fwrite(buffer, len, 1, f_err); + ret = fwrite(buffer, len, 1, f_err); } + +done: + free(buffer); + return ret; } const char *log_get_level(int level) -- 2.25.1