Merge branch 'ime-support' of https://github.com/DDNStorage/fio-public into ddn-ime
authorJens Axboe <axboe@kernel.dk>
Fri, 17 Aug 2018 19:34:21 +0000 (13:34 -0600)
committerJens Axboe <axboe@kernel.dk>
Fri, 17 Aug 2018 19:34:21 +0000 (13:34 -0600)
* 'ime-support' of https://github.com/DDNStorage/fio-public:
  Add support for DDN's Infinite Memory Engine

1  2 
HOWTO
Makefile
configure
options.c

diff --combined HOWTO
index 743144f03d14f76d46cf43d5191cf7217c4cd849,c3dd964a17b50af152f152fb808d1bffdc950c57..ff7aa096495a969aea9eddb0c8159f8054b6b0d1
--- 1/HOWTO
--- 2/HOWTO
+++ b/HOWTO
@@@ -283,8 -283,7 +283,8 @@@ Command line option
  
  .. option:: --aux-path=path
  
 -      Use this `path` for fio state generated files.
 +      Use the directory specified by `path` for generated state files instead
 +      of the current working directory.
  
  Any parameters following the options will be assumed to be job files, unless
  they match a job file parameter. Multiple job files can be listed and each job
@@@ -749,15 -748,12 +749,15 @@@ Target file/devic
        assigned equally distributed to job clones created by :option:`numjobs` as
        long as they are using generated filenames. If specific `filename(s)` are
        set fio will use the first listed directory, and thereby matching the
 -      `filename` semantic which generates a file each clone if not specified, but
 -      let all clones use the same if set.
 +      `filename` semantic (which generates a file for each clone if not
 +      specified, but lets all clones use the same file if set).
  
        See the :option:`filename` option for information on how to escape "``:``" and
        "``\``" characters within the directory path itself.
  
 +      Note: To control the directory fio will use for internal state files
 +      use :option:`--aux-path`.
 +
  .. option:: filename=str
  
        Fio normally makes up a `filename` based on the job name, thread number, and
  
        Unlink job files after each iteration or loop.  Default: false.
  
 -.. option:: zonesize=int
 +.. option:: zonerange=int
  
 -      Divide a file into zones of the specified size. See :option:`zoneskip`.
 +      Size of a single zone in which I/O occurs. See also :option:`zonesize`
 +      and :option:`zoneskip`.
  
 -.. option:: zonerange=int
 +.. option:: zonesize=int
  
 -      Give size of an I/O zone.  See :option:`zoneskip`.
 +      Number of bytes to transfer before skipping :option:`zoneskip`
 +      bytes. If this parameter is smaller than :option:`zonerange` then only
 +      a fraction of each zone with :option:`zonerange` bytes will be
 +      accessed.  If this parameter is larger than :option:`zonerange` then
 +      each zone will be accessed multiple times before skipping
  
  .. option:: zoneskip=int
  
 -      Skip the specified number of bytes when :option:`zonesize` data has been
 -      read. The two zone options can be used to only do I/O on zones of a file.
 +      Skip the specified number of bytes when :option:`zonesize` data have
 +      been transferred. The three zone options can be used to do strided I/O
 +      on a file.
  
  
  I/O type
@@@ -1835,15 -1825,6 +1835,15 @@@ I/O engin
                        (RBD) via librbd without the need to use the kernel rbd driver. This
                        ioengine defines engine specific options.
  
 +              **http**
 +                      I/O engine supporting GET/PUT requests over HTTP(S) with libcurl to
 +                      a WebDAV or S3 endpoint.  This ioengine defines engine specific options.
 +
 +                      This engine only supports direct IO of iodepth=1; you need to scale this
 +                      via numjobs. blocksize defines the size of the objects to be created.
 +
 +                      TRIM is translated to object deletion.
 +
                **gfapi**
                        Using GlusterFS libgfapi sync interface to direct access to
                        GlusterFS volumes without having to go through FUSE.  This ioengine
                        mounted with DAX on a persistent memory device through the PMDK
                        libpmem library.
  
+               **ime_psync**
+                       Synchronous read and write using DDN's Infinite Memory Engine (IME).
+                       This engine is very basic and issues calls to IME whenever an IO is
+                       queued.
+               **ime_psyncv**
+                       Synchronous read and write using DDN's Infinite Memory Engine (IME).
+                       This engine uses iovecs and will try to stack as much IOs as possible
+                       (if the IOs are "contiguous" and the IO depth is not exceeded)
+                       before issuing a call to IME.
+               **ime_aio**
+                       Asynchronous read and write using DDN's Infinite Memory Engine (IME).
+                       This engine will try to stack as much IOs as possible by creating
+                       requests for IME. FIO will then decide when to commit these requests.
  I/O engine specific parameters
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
@@@ -2124,54 -2121,6 +2140,54 @@@ with the caveat that when used on the c
                transferred to the device. The writefua option is ignored with this
                selection.
  
 +.. option:: http_host=str : [http]
 +
 +      Hostname to connect to. For S3, this could be the bucket hostname.
 +      Default is **localhost**
 +
 +.. option:: http_user=str : [http]
 +
 +      Username for HTTP authentication.
 +
 +.. option:: http_pass=str : [http]
 +
 +      Password for HTTP authentication.
 +
 +.. option:: https=str : [http]
 +
 +      Enable HTTPS instead of http. *on* enables HTTPS; *insecure*
 +      will enable HTTPS, but disable SSL peer verification (use with
 +      caution!). Default is **off**
 +
 +.. option:: http_mode=str : [http]
 +
 +      Which HTTP access mode to use: *webdav*, *swift*, or *s3*.
 +      Default is **webdav**
 +
 +.. option:: http_s3_region=str : [http]
 +
 +      The S3 region/zone string.
 +      Default is **us-east-1**
 +
 +.. option:: http_s3_key=str : [http]
 +
 +      The S3 secret key.
 +
 +.. option:: http_s3_keyid=str : [http]
 +
 +      The S3 key/access id.
 +
 +.. option:: http_swift_auth_token=str : [http]
 +
 +      The Swift auth token. See the example configuration file on how
 +      to retrieve this.
 +
 +.. option:: http_verbose=int : [http]
 +
 +      Enable verbose requests from libcurl. Useful for debugging. 1
 +      turns on verbose logging from libcurl, 2 additionally enables
 +      HTTP IO tracing. Default is **0**
 +
  I/O depth
  ~~~~~~~~~
  
@@@ -2982,11 -2931,9 +2998,11 @@@ Measurements and reportin
  .. option:: write_iops_log=str
  
        Same as :option:`write_bw_log`, but writes an IOPS file (e.g.
 -      :file:`name_iops.x.log`) instead. See :option:`write_bw_log` for
 -      details about the filename format and `Log File Formats`_ for how data
 -      is structured within the file.
 +      :file:`name_iops.x.log`) instead. Because fio defaults to individual
 +      I/O logging, the value entry in the IOPS log will be 1 unless windowed
 +      logging (see :option:`log_avg_msec`) has been enabled. See
 +      :option:`write_bw_log` for details about the filename format and `Log
 +      File Formats`_ for how data is structured within the file.
  
  .. option:: log_avg_msec=int
  
@@@ -3871,16 -3818,17 +3887,16 @@@ on the type of log, it will be one of t
        **2**
                I/O is a TRIM
  
 -The entry's *block size* is always in bytes. The *offset* is the offset, in bytes,
 -from the start of the file, for that particular I/O. The logging of the offset can be
 +The entry's *block size* is always in bytes. The *offset* is the position in bytes
 +from the start of the file for that particular I/O. The logging of the offset can be
  toggled with :option:`log_offset`.
  
 -Fio defaults to logging every individual I/O.  When IOPS are logged for individual
 -I/Os the *value* entry will always be 1. If windowed logging is enabled through
 -:option:`log_avg_msec`, fio logs the average values over the specified period of time.
 -If windowed logging is enabled and :option:`log_max_value` is set, then fio logs
 -maximum values in that window instead of averages. Since *data direction*, *block
 -size* and *offset* are per-I/O values, if windowed logging is enabled they
 -aren't applicable and will be 0.
 +Fio defaults to logging every individual I/O but when windowed logging is set
 +through :option:`log_avg_msec`, either the average (by default) or the maximum
 +(:option:`log_max_value` is set) *value* seen over the specified period of time
 +is recorded. Each *data direction* seen within the window period will aggregate
 +its values in a separate row. Further, when using windowed logging the *block
 +size* and *offset* entries will always contain 0.
  
  Client/Server
  -------------
diff --combined Makefile
index b981b45245dcb22a2843cf4f7abdbe4c09d4e715,dc28ece4332735ca2c0d128de210be75a4d1b80e..e8e15fe863ae1a4bbf5511f222000dfd5c6b800f
+++ b/Makefile
@@@ -50,7 -50,7 +50,7 @@@ SOURCE :=     $(sort $(patsubst $(SRCDIR)/%
                gettime-thread.c helpers.c json.c idletime.c td_error.c \
                profiles/tiobench.c profiles/act.c io_u_queue.c filelock.c \
                workqueue.c rate-submit.c optgroup.c helper_thread.c \
 -              steadystate.c
 +              steadystate.c zone-dist.c
  
  ifdef CONFIG_LIBHDFS
    HDFSFLAGS= -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux -I $(FIO_LIBHDFS_INCLUDE)
@@@ -101,9 -101,6 +101,9 @@@ endi
  ifdef CONFIG_RBD
    SOURCE += engines/rbd.c
  endif
 +ifdef CONFIG_HTTP
 +  SOURCE += engines/http.c
 +endif
  SOURCE += oslib/asprintf.c
  ifndef CONFIG_STRSEP
    SOURCE += oslib/strsep.c
@@@ -145,6 -142,9 +145,9 @@@ endi
  ifdef CONFIG_LIBPMEM
    SOURCE += engines/libpmem.c
  endif
+ ifdef CONFIG_IME
+   SOURCE += engines/ime.c
+ endif
  
  ifeq ($(CONFIG_TARGET_OS), Linux)
    SOURCE += diskutil.c fifo.c blktrace.c cgroup.c trim.c engines/sg.c \
diff --combined configure
index a03f7fa004a1c8c006e724538ae77ca54aa43cad,29ab39b98ea6deb926f4c7962209e1fd023d813e..fb8b2433a7a743255f64e934643aea70552aac29
+++ b/configure
@@@ -14,13 -14,12 +14,13 @@@ els
  fi
  
  TMPC="${TMPDIR1}/fio-conf-${RANDOM}-$$-${RANDOM}.c"
 +TMPC2="${TMPDIR1}/fio-conf-${RANDOM}-$$-${RANDOM}-2.c"
  TMPO="${TMPDIR1}/fio-conf-${RANDOM}-$$-${RANDOM}.o"
  TMPE="${TMPDIR1}/fio-conf-${RANDOM}-$$-${RANDOM}.exe"
  
  # NB: do not call "exit" in the trap handler; this is buggy with some shells;
  # see <1285349658-3122-1-git-send-email-loic.minier@linaro.org>
 -trap "rm -f $TMPC $TMPO $TMPE" EXIT INT QUIT TERM
 +trap "rm -f $TMPC $TMPC2 $TMPO $TMPE" EXIT INT QUIT TERM
  
  rm -rf config.log
  
@@@ -182,8 -181,6 +182,8 @@@ for opt d
    ;;
    --disable-rbd) disable_rbd="yes"
    ;;
 +  --disable-http) disable_http="yes"
 +  ;;
    --disable-gfapi) disable_gfapi="yes"
    ;;
    --enable-libhdfs) libhdfs="yes"
    ;;
    --disable-native) disable_native="yes"
    ;;
+   --with-ime=*) ime_path="$optarg"
+   ;;
    --help)
      show_help="yes"
      ;;
@@@ -233,6 -232,7 +235,7 @@@ if test "$show_help" = "yes" ; the
    echo "--disable-optimizations Don't enable compiler optimizations"
    echo "--enable-cuda           Enable GPUDirect RDMA support"
    echo "--disable-native        Don't build for native host"
+   echo "--with-ime=             Install path for DDN's Infinite Memory Engine"
    exit $exit_val
  fi
  
@@@ -1569,61 -1569,6 +1572,61 @@@ if compile_prog "" "" "ipv6"; the
  fi
  print_config "IPv6 helpers" "$ipv6"
  
 +##########################################
 +# check for http
 +if test "$http" != "yes" ; then
 +  http="no"
 +fi
 +# check for openssl >= 1.1.0, which uses an opaque HMAC_CTX pointer
 +cat > $TMPC << EOF
 +#include <curl/curl.h>
 +#include <openssl/hmac.h>
 +
 +int main(int argc, char **argv)
 +{
 +  CURL *curl;
 +  HMAC_CTX *ctx;
 +
 +  curl = curl_easy_init();
 +  curl_easy_cleanup(curl);
 +
 +  ctx = HMAC_CTX_new();
 +  HMAC_CTX_reset(ctx);
 +  HMAC_CTX_free(ctx);
 +  return 0;
 +}
 +EOF
 +# openssl < 1.1.0 uses the HMAC_CTX type directly
 +cat > $TMPC2 << EOF
 +#include <curl/curl.h>
 +#include <openssl/hmac.h>
 +
 +int main(int argc, char **argv)
 +{
 +  CURL *curl;
 +  HMAC_CTX ctx;
 +
 +  curl = curl_easy_init();
 +  curl_easy_cleanup(curl);
 +
 +  HMAC_CTX_init(&ctx);
 +  HMAC_CTX_cleanup(&ctx);
 +  return 0;
 +}
 +EOF
 +if test "$disable_http" != "yes"; then
 +  HTTP_LIBS="-lcurl -lssl -lcrypto"
 +  if compile_prog "" "$HTTP_LIBS" "curl-new-ssl"; then
 +    output_sym "CONFIG_HAVE_OPAQUE_HMAC_CTX"
 +    http="yes"
 +    LIBS="$HTTP_LIBS $LIBS"
 +  elif mv $TMPC2 $TMPC && compile_prog "" "$HTTP_LIBS" "curl-old-ssl"; then
 +    http="yes"
 +    LIBS="$HTTP_LIBS $LIBS"
 +  fi
 +fi
 +print_config "http engine" "$http"
 +
  ##########################################
  # check for rados
  if test "$rados" != "yes" ; then
@@@ -1962,6 -1907,29 +1965,29 @@@ print_config "PMDK dev-dax engine" "$de
  # Report whether libpmem engine is enabled
  print_config "PMDK libpmem engine" "$pmem"
  
+ ##########################################
+ # Check whether we support DDN's IME
+ if test "$libime" != "yes" ; then
+   libime="no"
+ fi
+ cat > $TMPC << EOF
+ #include <ime_native.h>
+ int main(int argc, char **argv)
+ {
+   int rc;
+   ime_native_init();
+   rc = ime_native_finalize();
+   return 0;
+ }
+ EOF
+ if compile_prog "-I${ime_path}/include" "-L${ime_path}/lib -lim_client" "libime"; then
+   libime="yes"
+   CFLAGS="-I${ime_path}/include $CFLAGS"
+   LDFLAGS="-Wl,-rpath ${ime_path}/lib -L${ime_path}/lib $LDFLAGS"
+   LIBS="-lim_client $LIBS"
+ fi
+ print_config "DDN's Infinite Memory Engine" "$libime"
  ##########################################
  # Check if we have lex/yacc available
  yacc="no"
  if test "$ipv6" = "yes" ; then
    output_sym "CONFIG_IPV6"
  fi
 +if test "$http" = "yes" ; then
 +  output_sym "CONFIG_HTTP"
 +fi
  if test "$rados" = "yes" ; then
    output_sym "CONFIG_RADOS"
  fi
  if test "$pmem" = "yes" ; then
    output_sym "CONFIG_LIBPMEM"
  fi
+ if test "$libime" = "yes" ; then
+   output_sym "CONFIG_IME"
+ fi
  if test "$arith" = "yes" ; then
    output_sym "CONFIG_ARITHMETIC"
    if test "$yacc_is_bison" = "yes" ; then
diff --combined options.c
index 9ee1ba3c93204f5d6f8953cf188ec3010fc921f9,83f86ce04b533071ef2026a7b5b4413727e22cf5..1c35acc76e57dc8865742ffe241df876ed38bcac
+++ b/options.c
@@@ -959,6 -959,48 +959,6 @@@ static int zone_split_ddir(struct threa
        return 0;
  }
  
 -static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir)
 -{
 -      unsigned int i, j, sprev, aprev;
 -      uint64_t sprev_sz;
 -
 -      td->zone_state_index[ddir] = malloc(sizeof(struct zone_split_index) * 100);
 -
 -      sprev_sz = sprev = aprev = 0;
 -      for (i = 0; i < td->o.zone_split_nr[ddir]; i++) {
 -              struct zone_split *zsp = &td->o.zone_split[ddir][i];
 -
 -              for (j = aprev; j < aprev + zsp->access_perc; j++) {
 -                      struct zone_split_index *zsi = &td->zone_state_index[ddir][j];
 -
 -                      zsi->size_perc = sprev + zsp->size_perc;
 -                      zsi->size_perc_prev = sprev;
 -
 -                      zsi->size = sprev_sz + zsp->size;
 -                      zsi->size_prev = sprev_sz;
 -              }
 -
 -              aprev += zsp->access_perc;
 -              sprev += zsp->size_perc;
 -              sprev_sz += zsp->size;
 -      }
 -}
 -
 -/*
 - * Generate state table for indexes, so we don't have to do it inline from
 - * the hot IO path
 - */
 -static void td_zone_gen_index(struct thread_data *td)
 -{
 -      int i;
 -
 -      td->zone_state_index = malloc(DDIR_RWDIR_CNT *
 -                                      sizeof(struct zone_split_index *));
 -
 -      for (i = 0; i < DDIR_RWDIR_CNT; i++)
 -              __td_zone_gen_index(td, i);
 -}
 -
  static int parse_zoned_distribution(struct thread_data *td, const char *input,
                                    bool absolute)
  {
                return ret;
        }
  
 -      if (!ret)
 -              td_zone_gen_index(td);
 -      else {
 +      if (ret) {
                for (i = 0; i < DDIR_RWDIR_CNT; i++)
                        td->o.zone_split_nr[i] = 0;
        }
@@@ -1845,6 -1889,17 +1845,17 @@@ struct fio_option fio_options[FIO_MAX_O
                          },
  
  #endif
+ #ifdef CONFIG_IME
+                         { .ival = "ime_psync",
+                           .help = "DDN's IME synchronous IO engine",
+                         },
+                         { .ival = "ime_psyncv",
+                           .help = "DDN's IME synchronous IO engine using iovecs",
+                         },
+                         { .ival = "ime_aio",
+                           .help = "DDN's IME asynchronous IO engine",
+                         },
+ #endif
  #ifdef CONFIG_LINUX_DEVDAX
                          { .ival = "dev-dax",
                            .help = "DAX Device based IO engine",
                          { .ival = "libpmem",
                            .help = "PMDK libpmem based IO engine",
                          },
 +#endif
 +#ifdef CONFIG_HTTP
 +                        { .ival = "http",
 +                          .help = "HTTP (WebDAV/S3) IO engine",
 +                        },
  #endif
                },
        },