Merge pull request #7 from hjelmn/master
Add mdtest to IOR repo and update backends to support mdtestmaster
commit
e1968cd4ad
|
@ -0,0 +1,9 @@
|
|||
IOR NEWS
|
||||
========
|
||||
|
||||
Last updated 2017-06
|
||||
|
||||
3.0.2
|
||||
|
||||
- IOR and mdtest now share a common codebase. This will make it easier
|
||||
run performance benchmarks on new hardware.
|
10
bootstrap
10
bootstrap
|
@ -1,11 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
aclocal -I config || exit 1
|
||||
#libtoolize --automake --copy --force || exit 1
|
||||
autoheader || exit 1
|
||||
automake --add-missing --copy --force-missing --foreign || exit 1
|
||||
#autoconf --force --warnings=all || exit 1
|
||||
autoconf --force || exit 1
|
||||
rm -fr autom4te*.cache
|
||||
exit 0
|
||||
autoreconf -ivf
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
# Read metadata from the META file.
|
||||
##*****************************************************************************
|
||||
|
||||
m4_define([META_FILE], m4_include([META]))
|
||||
m4_define([META_PACKAGE_NAME], regexp(META_FILE, [^Package:\s*\(.*\)], [\1]))
|
||||
m4_define([META_PACKAGE_VERSION], regexp(META_FILE, [^Version:\s*\(.*\)$], [\1]))
|
||||
|
||||
AC_DEFUN([X_AC_META], [
|
||||
AC_MSG_CHECKING([metadata])
|
||||
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -2,8 +2,12 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.62])
|
||||
AC_INIT
|
||||
AC_CONFIG_MACRO_DIR([config])
|
||||
|
||||
AC_INIT([META_PACKAGE_NAME],[META_PACKAGE_VERSION],[],[META_PACKAGE_NAME])
|
||||
|
||||
X_AC_META
|
||||
|
||||
AC_CONFIG_AUX_DIR([config])
|
||||
AC_CONFIG_SRCDIR([src/ior.c])
|
||||
AC_CONFIG_HEADER([src/config.h])
|
||||
|
@ -11,22 +15,25 @@ AC_CONFIG_HEADER([src/config.h])
|
|||
AC_CANONICAL_HOST
|
||||
|
||||
# Automake support
|
||||
AM_INIT_AUTOMAKE([$META_NAME], [$META_VERSION], [check-news dist-bzip2 gnu no-define])
|
||||
AM_INIT_AUTOMAKE([check-news dist-bzip2 gnu no-define])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
# Checks for programs.
|
||||
AX_PROG_CC_MPI
|
||||
|
||||
# No reason not to require modern C at this point
|
||||
AC_PROG_CC_C99
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([fcntl.h libintl.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/statfs.h sys/statvfs.h sys/time.h unistd.h wchar.h plfs.h hdfs.h beegfs/beegfs.h])
|
||||
AC_CHECK_HEADERS([fcntl.h libintl.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/statfs.h sys/statvfs.h sys/time.h sys/param.h sys/mount.h unistd.h wchar.h hdfs.h beegfs/beegfs.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([getpagesize gettimeofday memset mkdir pow putenv realpath regcomp sqrt strcasecmp strchr strerror strncasecmp strstr uname])
|
||||
AC_CHECK_FUNCS([getpagesize gettimeofday memset mkdir pow putenv realpath regcomp sqrt strcasecmp strchr strerror strncasecmp strstr uname statfs statvfs])
|
||||
AC_SEARCH_LIBS([sqrt], [m], [],
|
||||
[AC_MSG_ERROR([Math library not found])])
|
||||
|
||||
|
@ -109,17 +116,6 @@ AM_COND_IF([USE_NCMPI_AIORI],[
|
|||
AC_DEFINE([USE_NCMPI_AIORI], [], [Build NCMPI backend AIORI])
|
||||
])
|
||||
|
||||
# PLFS IO support
|
||||
AC_ARG_WITH([plfs],
|
||||
[AS_HELP_STRING([--with-plfs],
|
||||
[support IO with PLFS backend @<:@default=no@:>@])],
|
||||
[],
|
||||
[with_plfs=no])
|
||||
AM_CONDITIONAL([USE_PLFS_AIORI], [test x$with_plfs = xyes])
|
||||
AM_COND_IF([USE_PLFS_AIORI],[
|
||||
AC_DEFINE([USE_PLFS_AIORI], [], [Build PLFS backend AIORI])
|
||||
])
|
||||
|
||||
# POSIX IO support
|
||||
AC_ARG_WITH([posix],
|
||||
[AS_HELP_STRING([--with-posix],
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
dist_data_DATA = USER_GUIDE
|
||||
dist_man_MANS = mdtest.1
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
.TH mdtest 1 "2010-05-05" "mdtest-1.8.3" "mdtest"
|
||||
.SH NAME
|
||||
mdtest \- test file system metadata performance
|
||||
.SH SYNOPSIS
|
||||
.B mdtest
|
||||
.I "[-options]"
|
||||
.SH DESCRIPTION
|
||||
.B mdtest
|
||||
is a file system metadata performance test designed to run
|
||||
in a cluster MPI environment against parallel file systems.
|
||||
.PP
|
||||
In each iteration of the test, each MPI task creates, stats, and removes
|
||||
the specified number of directories and/or files and measures the performance
|
||||
in ops/second. After all the iterations complete, the maximum, minimum,
|
||||
mean ops/sec and the std. deviation are reported for each operation.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I "-b" branching_factor
|
||||
The branching factor of the hierarchical directory structure [default: 1].
|
||||
.TP
|
||||
.I "-B"
|
||||
No barriers will be taken between the phases (create/stat/remove) of the tests.
|
||||
.TP
|
||||
.I "-c"
|
||||
Use ``collective creates'', meaning task 0 does all the creates.
|
||||
.TP
|
||||
.I "-C"
|
||||
Only perform the create phase of the tests.
|
||||
.TP
|
||||
.I "-d" testdir[@testdir2]
|
||||
The directory in which the tests will run. For multiple pathes, must use fully-qualified pathnames.
|
||||
[default: working directory of mdtest].
|
||||
.TP
|
||||
.I "-D"
|
||||
Perform test on directories only (no files).
|
||||
.TP
|
||||
.I "-e" bytes
|
||||
Set the number of Bytes to read from each file [default: 0].
|
||||
.TP
|
||||
.I "-E"
|
||||
Only perform the read phase of the tests.
|
||||
.TP
|
||||
.I "-f" first
|
||||
The first number of tasks on which the test will run
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-F"
|
||||
Perform test on files only (no directories).
|
||||
.TP
|
||||
.I "-h"
|
||||
Display help message.
|
||||
.TP
|
||||
.I "-i" iterations
|
||||
The number of iterations the test will run
|
||||
[default: 1].
|
||||
.TP
|
||||
.I "-I" items_per_directory
|
||||
The number of items per directory in the tree [default: 0].
|
||||
.TP
|
||||
.I "-l" last
|
||||
The last number of tasks on which the test will run
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-L"
|
||||
Files/directories only created at the leaf level of the tree.
|
||||
.TP
|
||||
.I "-n" number_of_items
|
||||
Every process will creat/stat/remove # directories and files
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-N" stride
|
||||
Stride # between neighbor tasks for file/dir stat, 0 = local
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-p" seconds
|
||||
Pre-iteration delay (in seconds).
|
||||
.TP
|
||||
.I "-r"
|
||||
Only perform the remove phase of the tests.
|
||||
.TP
|
||||
.I "-R[seed]"
|
||||
Randomly stat files. There is an optional argument that provides a seed
|
||||
to the random number generator. (Note: There is no space between the
|
||||
.I "-R"
|
||||
and
|
||||
the seed if one is provided.)
|
||||
.TP
|
||||
.I "-s" stride
|
||||
Stride between the number of tasks for each test
|
||||
[default: 1].
|
||||
.TP
|
||||
.I "-S"
|
||||
Shared file access (file only, no directories).
|
||||
.TP
|
||||
.I "-t"
|
||||
Include unique working directory management overhead in the results
|
||||
(presumes
|
||||
.I "-u"
|
||||
option).
|
||||
.TP
|
||||
.I "-T"
|
||||
Only perform the stat phase of the tests.
|
||||
.TP
|
||||
.I "-u"
|
||||
Create a unique working directory for each task
|
||||
(presumes
|
||||
.I "-d"
|
||||
option).
|
||||
.TP
|
||||
.I "-v"
|
||||
Increase verbosity (each instance of option increments by one).
|
||||
.TP
|
||||
.I "-V" value
|
||||
Set verbosity value
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-w" bytes
|
||||
Set the number of Bytes to write to each file after it is created
|
||||
[default: 0].
|
||||
.TP
|
||||
.I "-z" tree_depth
|
||||
The depth of the hierarchical directory tree [default: 0].
|
||||
.SH EXAMPLES
|
||||
.SS "Example 1"
|
||||
.nf
|
||||
$ mpirun -n 2 ./mdtest -d /tmp/z -n 100 -i 2
|
||||
|
||||
-- started at 11/23/2009 09:05:29 --
|
||||
|
||||
mdtest-1.8.1 was launched with 2 total task(s) on 1 nodes
|
||||
Command line used: ./mdtest -d /tmp/z -n 100 -i 2
|
||||
Path: /tmp
|
||||
FS: 28.8 GiB Used FS: 8.6% 8.6%Inodes: 1.8 Mi Used Inodes: 5.1%
|
||||
|
||||
time to create tree: 0.000078 sec
|
||||
tree creation rate: 12826.617737 ops/sec
|
||||
|
||||
2 tasks, 200 files/directories
|
||||
|
||||
SUMMARY: (of 2 iterations)
|
||||
Operation Max Min Mean Std Dev
|
||||
--------- --- --- ---- -------
|
||||
Directory creation: 21489.415 17447.551 19468.483 2020.932
|
||||
Directory stat : 154657.227 28731.061 91694.144 62963.083
|
||||
Directory removal : 146756.613 21489.415 84123.014 62633.599
|
||||
File creation : 42024.989 28731.061 35378.025 6646.964
|
||||
File stat : 146756.613 17447.551 82102.082 64654.531
|
||||
File removal : 156884.384 42024.989 99454.686 57429.698
|
||||
|
||||
time to remove tree: 0.001031 sec
|
||||
tree removal rate: 970.005550 ops/sec
|
||||
|
||||
-- finished at 11/23/2009 09:05:29 --
|
||||
.fi
|
||||
.SS "Example 2"
|
||||
.nf
|
||||
$ mpirun -np 2 -H pc6 ./mdtest -d /tmp/z -b 2 -z 3 -I 10
|
||||
|
||||
-- started at 11/23/2009 09:09:23 --
|
||||
|
||||
mdtest-1.8.1 was launched with 2 total task(s) on 1 nodes
|
||||
Command line used: ./mdtest -d /tmp/z -b 2 -z 3 -I 10
|
||||
Path: /tmp
|
||||
FS: 28.8 GiB Used FS: 8.6% 8.6%Inodes: 1.8 Mi Used Inodes: 5.1%
|
||||
|
||||
time to create tree: 0.000765 sec
|
||||
tree creation rate: 19605.659084 ops/sec
|
||||
|
||||
2 tasks, 300 files/directories
|
||||
|
||||
SUMMARY: (of 1 iterations)
|
||||
Operation Max Min Mean Std Dev
|
||||
--------- --- --- ---- -------
|
||||
Directory creation: 29365.707 29365.707 29365.707 0.000
|
||||
Directory stat : 123701.455 123701.455 123701.455 0.000
|
||||
Directory removal : 25623.459 25623.459 25623.459 0.000
|
||||
File creation : 38704.743 38704.743 38704.743 0.000
|
||||
File stat : 125477.782 125477.782 125477.782 0.000
|
||||
File removal : 51911.845 51911.845 51911.845 0.000
|
||||
|
||||
time to remove tree: 0.000940 sec
|
||||
tree removal rate: 15960.060883 ops/sec
|
||||
|
||||
-- finished at 11/23/2009 09:09:23 --
|
||||
.fi
|
||||
|
||||
.SH "SEE ALSO"
|
||||
\fBhttp://sourceforge.net/projects/mdtest\fR
|
|
@ -1,70 +1,82 @@
|
|||
bin_PROGRAMS = ior
|
||||
bin_PROGRAMS = ior mdtest
|
||||
if USE_CAPS
|
||||
bin_PROGRAMS += IOR
|
||||
bin_PROGRAMS += IOR MDTEST
|
||||
endif
|
||||
|
||||
ior_SOURCES =
|
||||
noinst_HEADERS = ior.h utilities.h parse_options.h aiori.h iordef.h
|
||||
|
||||
extraSOURCES = aiori.c
|
||||
extraLDADD =
|
||||
extraLDFLAGS =
|
||||
extraCPPFLAGS =
|
||||
|
||||
ior_SOURCES = ior.c utilities.c parse_options.c
|
||||
ior_LDFLAGS =
|
||||
ior_LDADD =
|
||||
ior_CPPFLAGS =
|
||||
ior_LDFLAGS =
|
||||
ior_LDADD =
|
||||
|
||||
ior_SOURCES += ior.c utilities.c parse_options.c
|
||||
ior_SOURCES += ior.h utilities.h parse_options.h aiori.h iordef.h
|
||||
|
||||
mdtest_SOURCES = mdtest.c utilities.c
|
||||
mdtest_LDFLAGS =
|
||||
mdtest_LDADD =
|
||||
mdtest_CPPFLAGS =
|
||||
|
||||
if USE_HDFS_AIORI
|
||||
# TBD: figure out how to find the appropriate -I and -L dirs. Maybe we can
|
||||
# get them from the corresponding bin/ dir in $PATH, or pick an
|
||||
# environment var to use (and set it in modulefiles), or provide a
|
||||
# config-flag, to set a variable we use here.
|
||||
ior_SOURCES += aiori-HDFS.c
|
||||
ior_CPPFLAGS += -I/opt/hadoop-2.2.0/include
|
||||
ior_LDFLAGS += -L/opt/hadoop-2.2.0/lib/native
|
||||
ior_LDADD += -lhdfs
|
||||
extraSOURCES += aiori-HDFS.c
|
||||
extraCPPFLAGS += -I/opt/hadoop-2.2.0/include
|
||||
extraLDFLAGS += -L/opt/hadoop-2.2.0/lib/native
|
||||
extraLDADD += -lhdfs
|
||||
endif
|
||||
|
||||
if USE_HDF5_AIORI
|
||||
ior_SOURCES += aiori-HDF5.c
|
||||
ior_LDADD += -lhdf5 -lz
|
||||
extraSOURCES += aiori-HDF5.c
|
||||
extraLDADD += -lhdf5 -lz
|
||||
endif
|
||||
|
||||
if USE_MPIIO_AIORI
|
||||
ior_SOURCES += aiori-MPIIO.c
|
||||
extraSOURCES += aiori-MPIIO.c
|
||||
endif
|
||||
|
||||
if USE_NCMPI_AIORI
|
||||
ior_SOURCES += aiori-NCMPI.c
|
||||
ior_LDADD += -lpnetcdf
|
||||
endif
|
||||
|
||||
if USE_PLFS_AIORI
|
||||
# TBD: modulefiles don't add PLFS_VER to env, but you can find it embedded in
|
||||
# $PLFS_HOME. configure.ac should extract this for us. Then we should
|
||||
# add -D... to ior_CPPFLAGS, here. Then aiori-PLFS.c can conditionalize
|
||||
# compilation of calls that vary according to PLFS version.
|
||||
ior_SOURCES += aiori-PLFS.c
|
||||
ior_LDADD += -lplfs
|
||||
extraSOURCES += aiori-NCMPI.c
|
||||
extraLDADD += -lpnetcdf
|
||||
endif
|
||||
|
||||
if USE_POSIX_AIORI
|
||||
ior_SOURCES += aiori-POSIX.c
|
||||
extraSOURCES += aiori-POSIX.c
|
||||
endif
|
||||
|
||||
|
||||
if USE_S3_AIORI
|
||||
ior_SOURCES += aiori-S3.c
|
||||
extraSOURCES += aiori-S3.c
|
||||
if AWS4C_DIR
|
||||
ior_CPPFLAGS += $(AWS4C_CPPFLAGS)
|
||||
ior_LDFLAGS += $(AWS4C_LDFLAGS)
|
||||
extraCPPFLAGS += $(AWS4C_CPPFLAGS)
|
||||
extraLDFLAGS += $(AWS4C_LDFLAGS)
|
||||
endif
|
||||
ior_LDADD += -lcurl
|
||||
ior_LDADD += -lxml2
|
||||
ior_LDADD += -laws4c
|
||||
ior_LDADD += -laws4c_extra
|
||||
extraLDADD += -lcurl
|
||||
extraLDADD += -lxml2
|
||||
extraLDADD += -laws4c
|
||||
extraLDADD += -laws4c_extra
|
||||
endif
|
||||
|
||||
|
||||
ior_SOURCES += $(extraSOURCES)
|
||||
ior_LDFLAGS += $(extraLDFLAGS)
|
||||
ior_LDADD += $(extraLDADD)
|
||||
ior_CPPFLAGS += $(extraCPPFLAGS)
|
||||
|
||||
mdtest_SOURCES += $(extraSOURCES)
|
||||
mdtest_LDFLAGS += $(extraLDFLAGS)
|
||||
mdtest_LDADD += $(extraLDADD)
|
||||
mdtest_CPPFLAGS += $(extraCPPFLAGS)
|
||||
|
||||
IOR_SOURCES = $(ior_SOURCES)
|
||||
IOR_LDADD = $(ior_LDADD)
|
||||
IOT_CPPFLAGS = $(ior_CPPFLAGS)
|
||||
|
||||
MDTEST_SOURCES = $(mdtest_SOURCES)
|
||||
MDTEST_LDADD = $(mdtest_LDADD)
|
||||
MDTEST_CPPFLAGS = $(mdtest_CPPFLAGS)
|
||||
|
|
|
@ -96,15 +96,15 @@ static IOR_offset_t HDF5_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
|||
/************************** D E C L A R A T I O N S ***************************/
|
||||
|
||||
ior_aiori_t hdf5_aiori = {
|
||||
"HDF5",
|
||||
HDF5_Create,
|
||||
HDF5_Open,
|
||||
HDF5_Xfer,
|
||||
HDF5_Close,
|
||||
HDF5_Delete,
|
||||
HDF5_SetVersion,
|
||||
HDF5_Fsync,
|
||||
HDF5_GetFileSize
|
||||
.name = "HDF5",
|
||||
.create = HDF5_Create,
|
||||
.open = HDF5_Open,
|
||||
.xfer = HDF5_Xfer,
|
||||
.close = HDF5_Close,
|
||||
.delete = HDF5_Delete,
|
||||
.set_version = HDF5_SetVersion,
|
||||
.fsync = HDF5_Fsync,
|
||||
.get_file_size = HDF5_GetFileSize,
|
||||
};
|
||||
|
||||
static hid_t xferPropList; /* xfer property list */
|
||||
|
|
|
@ -114,15 +114,15 @@ static IOR_offset_t HDFS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
|||
/************************** D E C L A R A T I O N S ***************************/
|
||||
|
||||
ior_aiori_t hdfs_aiori = {
|
||||
"HDFS",
|
||||
HDFS_Create,
|
||||
HDFS_Open,
|
||||
HDFS_Xfer,
|
||||
HDFS_Close,
|
||||
HDFS_Delete,
|
||||
HDFS_SetVersion,
|
||||
HDFS_Fsync,
|
||||
HDFS_GetFileSize
|
||||
.name = "HDFS",
|
||||
.create = HDFS_Create,
|
||||
.open = HDFS_Open,
|
||||
.xfer = HDFS_Xfer,
|
||||
.close = HDFS_Close,
|
||||
.delete = HDFS_Delete,
|
||||
.set_version = HDFS_SetVersion,
|
||||
.fsync = HDFS_Fsync,
|
||||
.get_file_size = HDFS_GetFileSize,
|
||||
};
|
||||
|
||||
/***************************** F U N C T I O N S ******************************/
|
||||
|
|
|
@ -60,15 +60,15 @@ static IOR_offset_t NCMPI_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
|||
/************************** D E C L A R A T I O N S ***************************/
|
||||
|
||||
ior_aiori_t ncmpi_aiori = {
|
||||
"NCMPI",
|
||||
NCMPI_Create,
|
||||
NCMPI_Open,
|
||||
NCMPI_Xfer,
|
||||
NCMPI_Close,
|
||||
NCMPI_Delete,
|
||||
NCMPI_SetVersion,
|
||||
NCMPI_Fsync,
|
||||
NCMPI_GetFileSize
|
||||
.name = "NCMPI",
|
||||
.create = NCMPI_Create,
|
||||
.open = NCMPI_Open,
|
||||
.xfer = NCMPI_Xfer,
|
||||
.close = NCMPI_Close,
|
||||
.delete = NCMPI_Delete,
|
||||
.set_version = NCMPI_SetVersion,
|
||||
.fsync = NCMPI_Fsync,
|
||||
.get_file_size = NCMPI_GetFileSize,
|
||||
};
|
||||
|
||||
/***************************** F U N C T I O N S ******************************/
|
||||
|
|
473
src/aiori-PLFS.c
473
src/aiori-PLFS.c
|
@ -1,473 +0,0 @@
|
|||
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
* vim:expandtab:shiftwidth=8:tabstop=8:
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2009, Los Alamos National Security, LLC All rights reserved.
|
||||
* Copyright 2009. Los Alamos National Security, LLC. This software was produced
|
||||
* under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
|
||||
* Laboratory (LANL), which is operated by Los Alamos National Security, LLC for
|
||||
* the U.S. Department of Energy. The U.S. Government has rights to use,
|
||||
* reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
|
||||
* ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
|
||||
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is
|
||||
* modified to produce derivative works, such modified software should be
|
||||
* clearly marked, so as not to confuse it with the version available from
|
||||
* LANL.
|
||||
*
|
||||
* Additionally, redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* • Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* • Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* • Neither the name of Los Alamos National Security, LLC, Los Alamos National
|
||||
* Laboratory, LANL, the U.S. Government, nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/******************************************************************************\
|
||||
*
|
||||
* Implement of abstract I/O interface for PLFS.
|
||||
*
|
||||
\******************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ioctl.h> /* necessary for: */
|
||||
#define __USE_GNU /* O_DIRECT and */
|
||||
#include <fcntl.h> /* IO operations */
|
||||
#undef __USE_GNU
|
||||
#endif /* __linux__ */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> /* IO operations */
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
/*
|
||||
#ifdef HAVE_LUSTRE_LUSTRE_USER_H
|
||||
#include <lustre/lustre_user.h>
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include "ior.h"
|
||||
#include "aiori.h"
|
||||
#include "iordef.h"
|
||||
|
||||
#ifndef open64 /* necessary for TRU64 -- */
|
||||
# define open64 open /* unlikely, but may pose */
|
||||
#endif /* not open64 */ /* conflicting prototypes */
|
||||
|
||||
#ifndef lseek64 /* necessary for TRU64 -- */
|
||||
# define lseek64 lseek /* unlikely, but may pose */
|
||||
#endif /* not lseek64 */ /* conflicting prototypes */
|
||||
|
||||
#ifndef O_BINARY /* Required on Windows */
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#include "plfs.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
/**************************** P R O T O T Y P E S *****************************/
|
||||
static void *PLFS_Create(char *, IOR_param_t *);
|
||||
static void *PLFS_Open(char *, IOR_param_t *);
|
||||
static IOR_offset_t PLFS_Xfer(int, void *, IOR_size_t *,
|
||||
IOR_offset_t, IOR_param_t *);
|
||||
static void PLFS_Close(void *, IOR_param_t *);
|
||||
static void PLFS_Delete(char *, IOR_param_t *);
|
||||
static void PLFS_SetVersion(IOR_param_t *);
|
||||
static void PLFS_Fsync(void *, IOR_param_t *);
|
||||
static IOR_offset_t PLFS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||
|
||||
/************************** D E C L A R A T I O N S ***************************/
|
||||
|
||||
ior_aiori_t plfs_aiori = {
|
||||
"PLFS",
|
||||
PLFS_Create,
|
||||
PLFS_Open,
|
||||
PLFS_Xfer,
|
||||
PLFS_Close,
|
||||
PLFS_Delete,
|
||||
PLFS_SetVersion,
|
||||
PLFS_Fsync,
|
||||
PLFS_GetFileSize
|
||||
};
|
||||
|
||||
/***************************** F U N C T I O N S ******************************/
|
||||
|
||||
|
||||
/*
|
||||
* Create or open the file. Pass TRUE if creating and FALSE if opening an existing file.
|
||||
*/
|
||||
|
||||
static void *PLFS_Create_Or_Open( char *testFileName, IOR_param_t *param, unsigned char createFile ) {
|
||||
|
||||
Plfs_fd *plfs_fd = NULL;
|
||||
int fd_oflags = 0, plfs_return;
|
||||
|
||||
|
||||
/*
|
||||
* Check for unsupported flags.
|
||||
*
|
||||
* If they want RDWR, we don't know if they're going to try to do both, so we
|
||||
* can't default to either O_RDONLY or O_WRONLY. Thus, we error and exit.
|
||||
*
|
||||
* The other two, we just note that they are not supported and don't do them.
|
||||
*/
|
||||
|
||||
if ( param->openFlags & IOR_RDWR ) {
|
||||
ERR( "Opening or creating a file in RDWR is not implemented in PLFS" );
|
||||
}
|
||||
|
||||
if ( param->openFlags & IOR_EXCL ) {
|
||||
fprintf( stdout, "Opening or creating a file in Exclusive mode is not implemented in PLFS\n" );
|
||||
}
|
||||
|
||||
if ( param->openFlags & IOR_APPEND ) {
|
||||
fprintf( stdout, "Opening or creating a file for appending is not implemented in PLFS\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the flags to be used.
|
||||
*/
|
||||
|
||||
if ( createFile == TRUE ) {
|
||||
fd_oflags = O_CREAT;
|
||||
}
|
||||
|
||||
if ( param->openFlags & IOR_WRONLY ) {
|
||||
if ( !param->filePerProc ) {
|
||||
// in N-1 mode, only rank 0 truncates the file
|
||||
if ( rank != 0 ) {
|
||||
fd_oflags |= O_WRONLY;
|
||||
} else {
|
||||
fd_oflags |= O_TRUNC;
|
||||
fd_oflags |= O_WRONLY;
|
||||
}
|
||||
} else {
|
||||
// in N-N mode, everyone does truncate
|
||||
fd_oflags |= O_TRUNC;
|
||||
fd_oflags |= O_WRONLY;
|
||||
}
|
||||
} else {
|
||||
fd_oflags |= O_RDONLY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now see if O_DIRECT is needed.
|
||||
*/
|
||||
|
||||
if ( param->useO_DIRECT == TRUE ) {
|
||||
set_o_direct_flag( &fd_oflags );
|
||||
}
|
||||
|
||||
/*
|
||||
* For N-1 write, All other ranks wait for Rank 0 to open the file.
|
||||
* this is bec 0 does truncate and rest don't
|
||||
* it would be dangerous for all to do truncate as they might
|
||||
* truncate each other's writes
|
||||
*/
|
||||
|
||||
if (( param->openFlags & IOR_WRONLY ) &&
|
||||
( !param->filePerProc ) &&
|
||||
( rank != 0 )) {
|
||||
|
||||
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
||||
}
|
||||
|
||||
/*
|
||||
* Now rank zero can open and truncate, if necessary.
|
||||
*/
|
||||
|
||||
plfs_return = plfs_open( &( plfs_fd ), testFileName, fd_oflags, rank, 0666, NULL );
|
||||
|
||||
if ( plfs_return != 0 ) {
|
||||
ERR( "Failed to open the file" );
|
||||
}
|
||||
|
||||
/*
|
||||
* For N-1 write, Rank 0 waits for the other ranks to open the file after it has.
|
||||
*/
|
||||
|
||||
if (( param->openFlags & IOR_WRONLY ) &&
|
||||
( !param->filePerProc ) &&
|
||||
( rank == 0 )) {
|
||||
|
||||
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
||||
}
|
||||
|
||||
return ((void *) plfs_fd );
|
||||
}
|
||||
|
||||
/*
|
||||
* Create and open a file through the PLFS interface.
|
||||
*/
|
||||
|
||||
static void *PLFS_Create( char *testFileName, IOR_param_t * param ) {
|
||||
|
||||
return PLFS_Create_Or_Open( testFileName, param, TRUE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a file through the PLFS interface.
|
||||
*/
|
||||
static void *PLFS_Open( char *testFileName, IOR_param_t * param ) {
|
||||
|
||||
if ( param->openFlags & IOR_CREAT ) {
|
||||
return PLFS_Create_Or_Open( testFileName, param, TRUE );
|
||||
} else {
|
||||
return PLFS_Create_Or_Open( testFileName, param, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write or read access to file using the PLFS interface.
|
||||
*/
|
||||
|
||||
static IOR_offset_t PLFS_Xfer(int access, void *file, IOR_size_t * buffer,
|
||||
IOR_offset_t length, IOR_param_t * param) {
|
||||
|
||||
int xferRetries = 0;
|
||||
long long remaining = (long long)length;
|
||||
char * ptr = (char *)buffer;
|
||||
long long rc;
|
||||
off_t offset = param->offset;
|
||||
Plfs_fd * plfs_fd = (Plfs_fd *)file;
|
||||
|
||||
|
||||
while ( remaining > 0 ) {
|
||||
/* write/read file */
|
||||
if (access == WRITE) { /* WRITE */
|
||||
if (verbose >= VERBOSE_4) {
|
||||
fprintf( stdout, "task %d writing to offset %lld\n",
|
||||
rank,
|
||||
param->offset + length - remaining);
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = plfs_write( plfs_fd, ptr, remaining, offset, rank ); /* PLFS 2.4 */
|
||||
#else
|
||||
ssize_t bytes_written = 0;
|
||||
rc = plfs_write( plfs_fd, ptr, remaining, offset, rank, &bytes_written ); /* PLFS 2.5 */
|
||||
#endif
|
||||
if ( rc < 0 ) {
|
||||
ERR( "plfs_write() failed" );
|
||||
}
|
||||
|
||||
offset += rc;
|
||||
|
||||
if ( param->fsyncPerWrite == TRUE ) {
|
||||
PLFS_Fsync( plfs_fd, param );
|
||||
}
|
||||
} else { /* READ or CHECK */
|
||||
if (verbose >= VERBOSE_4) {
|
||||
fprintf( stdout, "task %d reading from offset %lld\n",
|
||||
rank,
|
||||
param->offset + length - remaining );
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = plfs_read( plfs_fd, ptr, remaining, param->offset ); /* PLFS 2.4 */
|
||||
#else
|
||||
ssize_t bytes_read = 0;
|
||||
rc = plfs_read( plfs_fd, ptr, remaining, param->offset, &bytes_read ); /* PLFS 2.5 */
|
||||
#endif
|
||||
|
||||
if ( rc == 0 ) {
|
||||
ERR( "plfs_read() returned EOF prematurely" );
|
||||
}
|
||||
|
||||
if ( rc < 0 ) {
|
||||
ERR( "plfs_read() failed" );
|
||||
}
|
||||
|
||||
offset += rc;
|
||||
}
|
||||
|
||||
if ( rc < remaining ) {
|
||||
fprintf(stdout, "WARNING: Task %d, partial %s, %lld of %lld bytes at offset %lld\n",
|
||||
rank,
|
||||
access == WRITE ? "plfs_write()" : "plfs_read()",
|
||||
rc, remaining,
|
||||
param->offset + length - remaining );
|
||||
|
||||
if ( param->singleXferAttempt == TRUE ) {
|
||||
MPI_CHECK( MPI_Abort( MPI_COMM_WORLD, -1 ), "barrier error" );
|
||||
}
|
||||
|
||||
if ( xferRetries > MAX_RETRY ) {
|
||||
ERR( "too many retries -- aborting" );
|
||||
}
|
||||
}
|
||||
|
||||
assert( rc >= 0 );
|
||||
assert( rc <= remaining );
|
||||
remaining -= rc;
|
||||
ptr += rc;
|
||||
xferRetries++;
|
||||
}
|
||||
|
||||
return ( length );
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform plfs_sync().
|
||||
*/
|
||||
|
||||
static void PLFS_Fsync( void *fd, IOR_param_t * param ) {
|
||||
|
||||
Plfs_fd *plfs_fd = (Plfs_fd *)fd;
|
||||
|
||||
if ( plfs_sync( plfs_fd ) != 0 ) {
|
||||
EWARN( "plfs_sync() failed" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a file through the PLFS interface.
|
||||
*/
|
||||
|
||||
static void PLFS_Close( void *fd, IOR_param_t * param ) {
|
||||
|
||||
Plfs_fd * plfs_fd = (Plfs_fd *)fd;
|
||||
int open_flags;
|
||||
long long rc;
|
||||
|
||||
if ( param->openFlags & IOR_WRONLY ) {
|
||||
open_flags = O_CREAT | O_WRONLY;
|
||||
} else {
|
||||
open_flags = O_RDONLY;
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = plfs_close( plfs_fd, rank, param->id, open_flags, NULL ); /* PLFS 2.4 */
|
||||
#else
|
||||
int ref_count = 0;
|
||||
rc = plfs_close( plfs_fd, rank, param->id, open_flags, NULL, &ref_count ); /* PLFS 2.5 */
|
||||
#endif
|
||||
|
||||
if ( rc != 0 ) {
|
||||
ERR( "plfs_close() failed" );
|
||||
}
|
||||
|
||||
free( fd );
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a file through the POSIX interface.
|
||||
*/
|
||||
static void PLFS_Delete( char *testFileName, IOR_param_t * param ) {
|
||||
|
||||
char errmsg[256];
|
||||
|
||||
if ( plfs_unlink( testFileName ) != 0 ) {
|
||||
sprintf(
|
||||
errmsg,
|
||||
"[RANK %03d]: plfs_unlink() of file \"%s\" failed\n",
|
||||
rank, testFileName);
|
||||
|
||||
EWARN( errmsg );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine api version.
|
||||
*/
|
||||
|
||||
static void PLFS_SetVersion( IOR_param_t * test ) {
|
||||
|
||||
strcpy( test->apiVersion, test->api );
|
||||
}
|
||||
|
||||
/*
|
||||
* Use plfs_getattr to return aggregate file size.
|
||||
*/
|
||||
|
||||
static IOR_offset_t PLFS_GetFileSize(
|
||||
IOR_param_t * test, MPI_Comm testComm, char *testFileName) {
|
||||
|
||||
int plfs_return;
|
||||
Plfs_fd * plfs_fd = NULL;
|
||||
struct stat stat_buf;
|
||||
IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
|
||||
long long rc;
|
||||
|
||||
|
||||
plfs_return = plfs_open( &( plfs_fd ), testFileName, O_RDONLY, rank, 0666, NULL );
|
||||
|
||||
if ( plfs_return != 0 ) {
|
||||
ERR( "plfs_open() failed before reading the file size attribute" );
|
||||
}
|
||||
|
||||
if ( plfs_getattr( plfs_fd, testFileName, &stat_buf, 1 ) != 0 ) {
|
||||
ERR( "plfs_getattr() failed" );
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = plfs_close( plfs_fd, rank, test->id, O_RDONLY, NULL ); /* PLFS 2.4 */
|
||||
#else
|
||||
int ref_count = 0;
|
||||
rc = plfs_close( plfs_fd, rank, test->id, O_RDONLY, NULL, &ref_count ); /* PLFS 2.5 */
|
||||
#endif
|
||||
|
||||
if ( rc != 0 ) {
|
||||
ERR( "plfs_close() failed after reading the file size attribute" );
|
||||
}
|
||||
|
||||
aggFileSizeFromStat = stat_buf.st_size;
|
||||
|
||||
if ( test->filePerProc == TRUE ) {
|
||||
MPI_CHECK(
|
||||
MPI_Allreduce(
|
||||
&aggFileSizeFromStat, &tmpSum, 1, MPI_LONG_LONG_INT, MPI_SUM, testComm ),
|
||||
"cannot total data moved" );
|
||||
|
||||
aggFileSizeFromStat = tmpSum;
|
||||
} else {
|
||||
MPI_CHECK(
|
||||
MPI_Allreduce(
|
||||
&aggFileSizeFromStat, &tmpMin, 1, MPI_LONG_LONG_INT, MPI_MIN, testComm ),
|
||||
"cannot total data moved" );
|
||||
|
||||
MPI_CHECK(
|
||||
MPI_Allreduce(
|
||||
&aggFileSizeFromStat, &tmpMax, 1, MPI_LONG_LONG_INT, MPI_MAX, testComm ),
|
||||
"cannot total data moved" );
|
||||
|
||||
if ( tmpMin != tmpMax ) {
|
||||
if ( rank == 0 ) {
|
||||
WARN( "inconsistent file size by different tasks" );
|
||||
}
|
||||
|
||||
/* incorrect, but now consistent across tasks */
|
||||
aggFileSizeFromStat = tmpMin;
|
||||
}
|
||||
}
|
||||
|
||||
return ( aggFileSizeFromStat );
|
||||
}
|
|
@ -78,15 +78,15 @@ static IOR_offset_t POSIX_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
|||
/************************** D E C L A R A T I O N S ***************************/
|
||||
|
||||
ior_aiori_t posix_aiori = {
|
||||
"POSIX",
|
||||
POSIX_Create,
|
||||
POSIX_Open,
|
||||
POSIX_Xfer,
|
||||
POSIX_Close,
|
||||
POSIX_Delete,
|
||||
POSIX_SetVersion,
|
||||
POSIX_Fsync,
|
||||
POSIX_GetFileSize
|
||||
.name = "POSIX",
|
||||
.create = POSIX_Create,
|
||||
.open = POSIX_Open,
|
||||
.xfer = POSIX_Xfer,
|
||||
.close = POSIX_Close,
|
||||
.delete = POSIX_Delete,
|
||||
.set_version = POSIX_SetVersion,
|
||||
.fsync = POSIX_Fsync,
|
||||
.get_file_size = POSIX_GetFileSize,
|
||||
};
|
||||
|
||||
/***************************** F U N C T I O N S ******************************/
|
||||
|
|
|
@ -132,45 +132,45 @@ static IOR_offset_t S3_GetFileSize(IOR_param_t*, MPI_Comm, char*);
|
|||
// N:1 writes use multi-part upload
|
||||
// N:N fails if "transfer-size" != "block-size" (because that requires "append")
|
||||
ior_aiori_t s3_aiori = {
|
||||
"S3",
|
||||
S3_Create,
|
||||
S3_Open,
|
||||
S3_Xfer,
|
||||
S3_Close,
|
||||
S3_Delete,
|
||||
S3_SetVersion,
|
||||
S3_Fsync,
|
||||
S3_GetFileSize
|
||||
.name = "S3",
|
||||
.create = S3_Create,
|
||||
.open = S3_Open,
|
||||
.xfer = S3_Xfer,
|
||||
.close = S3_Close,
|
||||
.delete = S3_Delete,
|
||||
.set_version = S3_SetVersion,
|
||||
.fsync = S3_Fsync,
|
||||
.get_file_size = S3_GetFileSize,
|
||||
};
|
||||
|
||||
// "S3", plus EMC-extensions enabled
|
||||
// N:1 writes use multi-part upload
|
||||
// N:N succeeds (because EMC-extensions support "append")
|
||||
ior_aiori_t s3_plus_aiori = {
|
||||
"S3_plus",
|
||||
S3_Create,
|
||||
S3_Open,
|
||||
S3_Xfer,
|
||||
S3_Close,
|
||||
S3_Delete,
|
||||
S3_SetVersion,
|
||||
S3_Fsync,
|
||||
S3_GetFileSize
|
||||
.name = "S3_plus",
|
||||
.create = S3_Create,
|
||||
.open = S3_Open,
|
||||
.xfer = S3_Xfer,
|
||||
.close = S3_Close,
|
||||
.delete = S3_Delete,
|
||||
.set_version = S3_SetVersion,
|
||||
.fsync = S3_Fsync,
|
||||
.get_file_size = S3_GetFileSize,
|
||||
};
|
||||
|
||||
// Use EMC-extensions for N:1 write, as well
|
||||
// N:1 writes use EMC byte-range
|
||||
// N:N succeeds because EMC-extensions support "append"
|
||||
ior_aiori_t s3_emc_aiori = {
|
||||
"S3_EMC",
|
||||
EMC_Create,
|
||||
EMC_Open,
|
||||
EMC_Xfer,
|
||||
EMC_Close,
|
||||
S3_Delete,
|
||||
S3_SetVersion,
|
||||
S3_Fsync,
|
||||
S3_GetFileSize
|
||||
.name = "S3_EMC",
|
||||
.create = EMC_Create,
|
||||
.open = EMC_Open,
|
||||
.xfer = EMC_Xfer,
|
||||
.close = EMC_Close,
|
||||
.delete = S3_Delete,
|
||||
.set_version = S3_SetVersion,
|
||||
.fsync = S3_Fsync,
|
||||
.get_file_size = S3_GetFileSize,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
* vim:expandtab:shiftwidth=8:tabstop=8:
|
||||
*/
|
||||
/******************************************************************************\
|
||||
* *
|
||||
* Copyright (c) 2003, The Regents of the University of California *
|
||||
* See the file COPYRIGHT for a complete copyright notice and license. *
|
||||
* *
|
||||
********************************************************************************
|
||||
*
|
||||
* Definitions and prototypes of abstract I/O interface
|
||||
*
|
||||
\******************************************************************************/
|
||||
|
||||
#include "aiori.h"
|
||||
|
||||
#if defined(HAVE_SYS_STATVFS_H)
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_STATFS_H)
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bind the global "backend" pointer to the requested backend AIORI's
|
||||
* function table.
|
||||
*/
|
||||
|
||||
ior_aiori_t *available_aiori[] = {
|
||||
|
||||
#ifdef USE_HDF5_AIORI
|
||||
&hdf5_aiori,
|
||||
#endif
|
||||
#ifdef USE_HDFS_AIORI
|
||||
&hdfs_aiori,
|
||||
#endif
|
||||
#ifdef USE_MPIIO_AIORI
|
||||
&mpiio_aiori,
|
||||
#endif
|
||||
#ifdef USE_NCMPI_AIORI
|
||||
&ncmpi_aiori,
|
||||
#endif
|
||||
#ifdef USE_POSIX_AIORI
|
||||
&posix_aiori,
|
||||
#endif
|
||||
#ifdef USE_S3_AIORI
|
||||
&s3_aiori,
|
||||
&s3_plus_aiori,
|
||||
&s3_emc_aiori,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* Default statfs implementation.
|
||||
*
|
||||
* @param[in] path Path to run statfs on
|
||||
* @param[out] statfs_buf AIORI statfs buffer
|
||||
*
|
||||
* This function provides a AIORI statfs for POSIX-compliant filesystems. It
|
||||
* uses statvfs is available and falls back on statfs.
|
||||
*/
|
||||
static int aiori_statfs (const char *path, ior_aiori_statfs_t *stat_buf, IOR_param_t * param)
|
||||
{
|
||||
int ret;
|
||||
#if defined(HAVE_STATVFS)
|
||||
struct statvfs statfs_buf;
|
||||
|
||||
ret = statvfs (path, &statfs_buf);
|
||||
#else
|
||||
struct statfs statfs_buf;
|
||||
|
||||
ret = statfs (path, &statfs_buf);
|
||||
#endif
|
||||
if (-1 == ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
stat_buf->f_bsize = statfs_buf.f_bsize;
|
||||
stat_buf->f_blocks = statfs_buf.f_blocks;
|
||||
stat_buf->f_bfree = statfs_buf.f_bfree;
|
||||
stat_buf->f_files = statfs_buf.f_files;
|
||||
stat_buf->f_ffree = statfs_buf.f_ffree;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aiori_mkdir (const char *path, mode_t mode, IOR_param_t * param)
|
||||
{
|
||||
return mkdir (path, mode);
|
||||
}
|
||||
|
||||
static int aiori_rmdir (const char *path, IOR_param_t * param)
|
||||
{
|
||||
return rmdir (path);
|
||||
}
|
||||
|
||||
static int aiori_access (const char *path, int mode, IOR_param_t * param)
|
||||
{
|
||||
return access (path, mode);
|
||||
}
|
||||
|
||||
static int aiori_stat (const char *path, struct stat *buf, IOR_param_t * param)
|
||||
{
|
||||
return stat (path, buf);
|
||||
}
|
||||
|
||||
const ior_aiori_t *aiori_select (const char *api)
|
||||
{
|
||||
for (ior_aiori_t **tmp = available_aiori ; *tmp != NULL; ++tmp) {
|
||||
if (NULL == api || strcasecmp(api, (*tmp)->name) == 0) {
|
||||
if (NULL == (*tmp)->statfs) {
|
||||
(*tmp)->statfs = aiori_statfs;
|
||||
}
|
||||
if (NULL == (*tmp)->mkdir) {
|
||||
(*tmp)->mkdir = aiori_mkdir;
|
||||
}
|
||||
if (NULL == (*tmp)->rmdir) {
|
||||
(*tmp)->rmdir = aiori_rmdir;
|
||||
}
|
||||
if (NULL == (*tmp)->access) {
|
||||
(*tmp)->access = aiori_access;
|
||||
}
|
||||
if (NULL == (*tmp)->stat) {
|
||||
(*tmp)->stat = aiori_stat;
|
||||
}
|
||||
return *tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int aiori_count (void)
|
||||
{
|
||||
return sizeof (available_aiori)/sizeof(available_aiori[0]) - 1;
|
||||
}
|
||||
|
||||
const char *aiori_default (void)
|
||||
{
|
||||
if (aiori_count () > 0) {
|
||||
return available_aiori[0]->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
20
src/aiori.h
20
src/aiori.h
|
@ -21,6 +21,8 @@
|
|||
# include <mpio.h>
|
||||
#endif /* not MPI_FILE_NULL */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "ior.h"
|
||||
#include "iordef.h" /* IOR Definitions */
|
||||
|
||||
|
@ -50,6 +52,15 @@
|
|||
#define IOR_IWOTH 0x0400 /* write permission: other */
|
||||
#define IOR_IXOTH 0x0800 /* execute permission: other */
|
||||
|
||||
typedef struct ior_aiori_statfs {
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
} ior_aiori_statfs_t;
|
||||
|
||||
typedef struct ior_aiori {
|
||||
char *name;
|
||||
void *(*create)(char *, IOR_param_t *);
|
||||
|
@ -61,6 +72,11 @@ typedef struct ior_aiori {
|
|||
void (*set_version)(IOR_param_t *);
|
||||
void (*fsync)(void *, IOR_param_t *);
|
||||
IOR_offset_t (*get_file_size)(IOR_param_t *, MPI_Comm, char *);
|
||||
int (*statfs) (const char *, ior_aiori_statfs_t *, IOR_param_t * param);
|
||||
int (*mkdir) (const char *path, mode_t mode, IOR_param_t * param);
|
||||
int (*rmdir) (const char *path, IOR_param_t * param);
|
||||
int (*access) (const char *path, int mode, IOR_param_t * param);
|
||||
int (*stat) (const char *path, struct stat *buf, IOR_param_t * param);
|
||||
} ior_aiori_t;
|
||||
|
||||
extern ior_aiori_t hdf5_aiori;
|
||||
|
@ -68,11 +84,13 @@ extern ior_aiori_t hdfs_aiori;
|
|||
extern ior_aiori_t mpiio_aiori;
|
||||
extern ior_aiori_t ncmpi_aiori;
|
||||
extern ior_aiori_t posix_aiori;
|
||||
extern ior_aiori_t plfs_aiori;
|
||||
extern ior_aiori_t s3_aiori;
|
||||
extern ior_aiori_t s3_plus_aiori;
|
||||
extern ior_aiori_t s3_emc_aiori;
|
||||
|
||||
const ior_aiori_t *aiori_select (const char *api);
|
||||
int aiori_count (void);
|
||||
const char *aiori_default (void);
|
||||
|
||||
IOR_offset_t MPIIO_GetFileSize(IOR_param_t * test, MPI_Comm testComm,
|
||||
char *testFileName);
|
||||
|
|
68
src/ior.c
68
src/ior.c
|
@ -50,34 +50,7 @@ int totalErrorCount = 0;
|
|||
double wall_clock_delta = 0;
|
||||
double wall_clock_deviation;
|
||||
|
||||
ior_aiori_t *backend;
|
||||
ior_aiori_t *available_aiori[] = {
|
||||
|
||||
#ifdef USE_HDF5_AIORI
|
||||
&hdf5_aiori,
|
||||
#endif
|
||||
#ifdef USE_HDFS_AIORI
|
||||
&hdfs_aiori,
|
||||
#endif
|
||||
#ifdef USE_MPIIO_AIORI
|
||||
&mpiio_aiori,
|
||||
#endif
|
||||
#ifdef USE_NCMPI_AIORI
|
||||
&ncmpi_aiori,
|
||||
#endif
|
||||
#ifdef USE_POSIX_AIORI
|
||||
&posix_aiori,
|
||||
#endif
|
||||
#ifdef USE_PLFS_AIORI
|
||||
&plfs_aiori,
|
||||
#endif
|
||||
#ifdef USE_S3_AIORI
|
||||
&s3_aiori,
|
||||
&s3_plus_aiori,
|
||||
&s3_emc_aiori,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
const ior_aiori_t *backend;
|
||||
|
||||
static void DestroyTests(IOR_test_t *tests_head);
|
||||
static void DisplayUsage(char **);
|
||||
|
@ -135,7 +108,7 @@ int main(int argc, char **argv)
|
|||
"cannot set errhandler"); */
|
||||
|
||||
/* Sanity check, we were compiled with SOME backend, right? */
|
||||
if (available_aiori[0] == NULL) {
|
||||
if (0 == aiori_count ()) {
|
||||
ERR("No IO backends compiled into ior. "
|
||||
"Run 'configure --with-<backend>', and recompile.");
|
||||
}
|
||||
|
@ -204,13 +177,16 @@ int main(int argc, char **argv)
|
|||
*/
|
||||
void init_IOR_Param_t(IOR_param_t * p)
|
||||
{
|
||||
assert(available_aiori[0] != NULL);
|
||||
const char *default_aiori = aiori_default ();
|
||||
|
||||
assert (NULL != default_aiori);
|
||||
|
||||
memset(p, 0, sizeof(IOR_param_t));
|
||||
|
||||
p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP;
|
||||
p->openFlags = IOR_RDWR | IOR_CREAT;
|
||||
|
||||
strncpy(p->api, available_aiori[0]->name, MAX_STR);
|
||||
strncpy(p->api, default_aiori, MAX_STR);
|
||||
strncpy(p->platform, "HOST(OSTYPE)", MAX_STR);
|
||||
strncpy(p->testFileName, "testFile", MAXPATHLEN);
|
||||
|
||||
|
@ -247,32 +223,20 @@ void init_IOR_Param_t(IOR_param_t * p)
|
|||
p->beegfs_chunkSize = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind the global "backend" pointer to the requested backend AIORI's
|
||||
* function table.
|
||||
*/
|
||||
static void AioriBind(char* api, IOR_param_t* param)
|
||||
{
|
||||
ior_aiori_t **tmp;
|
||||
|
||||
backend = NULL;
|
||||
for (tmp = available_aiori; *tmp != NULL; tmp++) {
|
||||
if (strcmp(api, (*tmp)->name) == 0) {
|
||||
backend = *tmp;
|
||||
break;
|
||||
backend = aiori_select (api);
|
||||
if (NULL != backend) {
|
||||
if (! strncmp(api, "S3", 2)) {
|
||||
if (! strcmp(api, "S3_EMC")) {
|
||||
param->curl_flags |= IOR_CURL_S3_EMC_EXT;
|
||||
} else {
|
||||
param->curl_flags &= ~(IOR_CURL_S3_EMC_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (backend == NULL) {
|
||||
} else {
|
||||
ERR("unrecognized IO API");
|
||||
}
|
||||
else if (! strncmp(api, "S3", 2)) {
|
||||
if (! strcmp(api, "S3_EMC"))
|
||||
param->curl_flags |= IOR_CURL_S3_EMC_EXT;
|
||||
else
|
||||
param->curl_flags &= ~(IOR_CURL_S3_EMC_EXT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue