Merge branch 'asprintf' of https://github.com/bvanassche/fio
authorJens Axboe <axboe@kernel.dk>
Wed, 21 Mar 2018 14:26:28 +0000 (08:26 -0600)
committerJens Axboe <axboe@kernel.dk>
Wed, 21 Mar 2018 14:26:28 +0000 (08:26 -0600)
* 'asprintf' of https://github.com/bvanassche/fio:
  verify: Simplify dump_buf()
  log: Modify the implementation such that it uses asprintf()
  Add an asprintf() implementation

Makefile
configure
log.c
oslib/asprintf.c [new file with mode: 0644]
oslib/asprintf.h [new file with mode: 0644]
verify.c

index eb3bddd6be095fc7a46bf8764e36eddb06d1a7bb..d45ba6b5585fe43ce793937f0fa5c87828c434b4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -104,6 +104,7 @@ endif
 ifdef CONFIG_RBD
   SOURCE += engines/rbd.c
 endif
+SOURCE += oslib/asprintf.c
 ifndef CONFIG_STRSEP
   SOURCE += oslib/strsep.c
 endif
index ddf03a6b8e1b12faddb1f4a9310d30d45214dac7..f6358630562229029bb409ee98fbe94df939f7d1 100755 (executable)
--- a/configure
+++ b/configure
@@ -783,6 +783,40 @@ if test "$disable_rdma" != "yes" && compile_prog "" "-lrdmacm" "rdma"; then
 fi
 print_config "rdmacm" "$rdmacm"
 
+##########################################
+# asprintf() and vasprintf() probes
+if test "$have_asprintf" != "yes" ; then
+  have_asprintf="no"
+fi
+cat > $TMPC << EOF
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+  return asprintf(NULL, "%s", "str") == 0;
+}
+EOF
+if compile_prog "" "" "have_asprintf"; then
+    have_asprintf="yes"
+fi
+print_config "asprintf()" "$have_asprintf"
+
+if test "$have_vasprintf" != "yes" ; then
+  have_vasprintf="no"
+fi
+cat > $TMPC << EOF
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+  return vasprintf(NULL, "%s", NULL) == 0;
+}
+EOF
+if compile_prog "" "" "have_vasprintf"; then
+    have_vasprintf="yes"
+fi
+print_config "vasprintf()" "$have_vasprintf"
+
 ##########################################
 # Linux fallocate probe
 if test "$linux_fallocate" != "yes" ; then
@@ -2169,6 +2203,12 @@ fi
 if test "$posix_pshared" = "yes" ; then
   output_sym "CONFIG_PSHARED"
 fi
+if test "$have_asprintf" = "yes" ; then
+    output_sym "HAVE_ASPRINTF"
+fi
+if test "$have_vasprintf" = "yes" ; then
+    output_sym "HAVE_VASPRINTF"
+fi
 if test "$linux_fallocate" = "yes" ; then
   output_sym "CONFIG_LINUX_FALLOCATE"
 fi
diff --git a/log.c b/log.c
index a327f6aa4c0e68f9e822e349984f31c3d509d9e2..7e8b13b31a84c906a09db6fce5044ef8e051fcae 100644 (file)
--- a/log.c
+++ b/log.c
@@ -5,8 +5,7 @@
 #include <syslog.h>
 
 #include "fio.h"
-
-#define LOG_START_SZ           512
+#include "oslib/asprintf.h"
 
 size_t log_info_buf(const char *buf, size_t len)
 {
@@ -29,63 +28,14 @@ size_t log_info_buf(const char *buf, size_t len)
                return fwrite(buf, len, 1, f_out);
 }
 
-static size_t valist_to_buf(char **buffer, const char *fmt, va_list src_args)
-{
-       size_t len, cur = LOG_START_SZ;
-       va_list args;
-
-       do {
-               *buffer = calloc(1, cur);
-               if (!*buffer)
-                       return 0;
-
-               va_copy(args, src_args);
-               len = vsnprintf(*buffer, cur, fmt, args);
-               va_end(args);
-
-               if (len < cur)
-                       break;
-
-               cur = len + 1;
-               free(*buffer);
-       } while (1);
-
-       return len;
-}
-
-/* allocate buffer, fill with prefix string followed by vararg string */
-static size_t prevalist_to_buf(char **buffer, const char *pre, int prelen,
-               const char *fmt, va_list src_args)
-{
-       size_t len, cur = LOG_START_SZ;
-       va_list args;
-
-       do {
-               *buffer = calloc(1, cur);
-               if (!*buffer)
-                       return 0;
-
-               va_copy(args, src_args);
-               memcpy(*buffer, pre, prelen);
-               len = prelen + vsnprintf(*buffer + prelen, cur - prelen, fmt, args);
-               va_end(args);
-
-               if (len < cur)
-                       break;
-
-               cur = len + 1;
-               free(*buffer);
-       } while (1);
-
-       return len;
-}
-
 size_t log_valist(const char *fmt, va_list args)
 {
        char *buffer;
-       size_t len;
+       int len;
 
-       len = valist_to_buf(&buffer, fmt, args);
+       len = vasprintf(&buffer, fmt, args);
+       if (len < 0)
+               return 0;
        len = log_info_buf(buffer, len);
        free(buffer);
 
@@ -95,10 +45,8 @@ size_t log_valist(const char *fmt, va_list args)
 /* add prefix for the specified type in front of the valist */
 void log_prevalist(int type, const char *fmt, va_list args)
 {
-       char pre[32];
-       char *buffer;
-       size_t len;
-       int prelen;
+       char *buf1, *buf2;
+       int len;
        pid_t pid;
 
        pid = gettid();
@@ -106,12 +54,16 @@ void log_prevalist(int type, const char *fmt, va_list args)
            && pid != *fio_debug_jobp)
                return;
 
-       prelen = snprintf(pre, sizeof pre, "%-8s %-5u ", debug_levels[type].name, (int) pid);
-       if (prelen > 0) {
-               len = prevalist_to_buf(&buffer, pre, prelen, fmt, args);
-               len = log_info_buf(buffer, len);
-               free(buffer);
-       }
+       len = vasprintf(&buf1, fmt, args);
+       if (len < 0)
+               return;
+       len = asprintf(&buf2, "%-8s %-5u %s", debug_levels[type].name,
+                      (int) pid, buf1);
+       free(buf1);
+       if (len < 0)
+               return;
+       len = log_info_buf(buf2, len);
+       free(buf2);
 }
 
 size_t log_info(const char *format, ...)
@@ -130,12 +82,13 @@ size_t __log_buf(struct buf_output *buf, const char *format, ...)
 {
        char *buffer;
        va_list args;
-       size_t len;
+       int len;
 
        va_start(args, format);
-       len = valist_to_buf(&buffer, format, args);
+       len = vasprintf(&buffer, format, args);
        va_end(args);
-
+       if (len < 0)
+               return 0;
        len = buf_output_add(buf, buffer, len);
        free(buffer);
 
@@ -152,13 +105,16 @@ int log_info_flush(void)
 
 size_t log_err(const char *format, ...)
 {
-       size_t ret, len;
+       size_t ret;
+       int len;
        char *buffer;
        va_list args;
 
        va_start(args, format);
-       len = valist_to_buf(&buffer, format, args);
+       len = vasprintf(&buffer, format, args);
        va_end(args);
+       if (len < 0)
+               return len;
 
        if (is_backend) {
                ret = fio_server_text_output(FIO_LOG_ERR, buffer, len);
diff --git a/oslib/asprintf.c b/oslib/asprintf.c
new file mode 100644 (file)
index 0000000..f1e7fd2
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "oslib/asprintf.h"
+
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+    va_list ap_copy;
+    char *str;
+    int len;
+
+#ifdef va_copy
+    va_copy(ap_copy, ap);
+#else
+    __va_copy(ap_copy, ap);
+#endif
+    len = vsnprintf(NULL, 0, fmt, ap_copy);
+    va_end(ap_copy);
+
+    if (len < 0)
+        return len;
+
+    len++;
+    str = malloc(len);
+    *strp = str;
+    return str ? vsnprintf(str, len, fmt, ap) : -1;
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf(char **strp, const char *fmt, ...)
+{
+    va_list arg;
+    int done;
+
+    va_start(arg, fmt);
+    done = vasprintf(strp, fmt, arg);
+    va_end(arg);
+
+    return done;
+}
+#endif
diff --git a/oslib/asprintf.h b/oslib/asprintf.h
new file mode 100644 (file)
index 0000000..1aa076b
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef FIO_ASPRINTF_H
+#define FIO_ASPRINTF_H
+
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **strp, const char *fmt, va_list ap);
+#endif
+#ifndef HAVE_ASPRINTF
+int asprintf(char **strp, const char *fmt, ...);
+#endif
+
+#endif /* FIO_ASPRINTF_H */
index d10670bb0c328b8ff520ec3e719876b7707ae775..c5fa24110143cb46cee4a6dad1db9a7e878c6a01 100644 (file)
--- a/verify.c
+++ b/verify.c
@@ -245,33 +245,23 @@ struct vcont {
 static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
                     const char *type, struct fio_file *f)
 {
-       char *ptr, fname[DUMP_BUF_SZ];
-       size_t buf_left = DUMP_BUF_SZ;
+       char *ptr, *fname;
+       char sep[2] = { FIO_OS_PATH_SEPARATOR, 0 };
        int ret, fd;
 
        ptr = strdup(f->file_name);
 
-       memset(fname, 0, sizeof(fname));
-       if (aux_path)
-               sprintf(fname, "%s%c", aux_path, FIO_OS_PATH_SEPARATOR);
-
-       strncpy(fname + strlen(fname), basename(ptr), buf_left - 1);
-
-       buf_left -= strlen(fname);
-       if (buf_left <= 0) {
+       if (asprintf(&fname, "%s%s%s.%llu.%s", aux_path ? : "",
+                    aux_path ? sep : "", basename(ptr), offset, type) < 0) {
                if (!fio_did_warn(FIO_WARN_VERIFY_BUF))
-                       log_err("fio: verify failure dump buffer too small\n");
-               free(ptr);
-               return;
+                       log_err("fio: not enough memory for dump buffer filename\n");
+               goto free_ptr;
        }
 
-       snprintf(fname + strlen(fname), buf_left, ".%llu.%s", offset, type);
-
        fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644);
        if (fd < 0) {
                perror("open verify buf file");
-               free(ptr);
-               return;
+               goto free_fname;
        }
 
        while (len) {
@@ -288,6 +278,11 @@ static void dump_buf(char *buf, unsigned int len, unsigned long long offset,
 
        close(fd);
        log_err("       %s data dumped as %s\n", type, fname);
+
+free_fname:
+       free(fname);
+
+free_ptr:
        free(ptr);
 }