DAOS backend cleanup (#266)
- remove legacy DAOS driver & update Readme. - update configure options to remove cart requirement - Optimize DFS file get_size Signed-off-by: Mohamad Chaarawi <mohamad.chaarawi@intel.com>master
parent
d750d323e3
commit
cb397242f9
73
README_DAOS
73
README_DAOS
|
@ -4,55 +4,13 @@ Building
|
||||||
The DAOS library must be installed on the system.
|
The DAOS library must be installed on the system.
|
||||||
|
|
||||||
./bootstrap
|
./bootstrap
|
||||||
./configure --prefix=iorInstallDir --with-daos=DIR --with-cart=DIR
|
./configure --prefix=iorInstallDir --with-daos=DIR
|
||||||
|
|
||||||
One must specify "--with-daos=/path/to/daos/install and --with-cart". When that
|
|
||||||
is specified the DAOS and DFS driver will be built.
|
|
||||||
|
|
||||||
The DAOS driver uses the DAOS API to open a container (or create it if it
|
|
||||||
doesn't exist first) then create an array object in that container (file) and
|
|
||||||
read/write to the array object using the daos Array API. The DAOS driver works
|
|
||||||
with IOR only (no mdtest support yet). The file name used by IOR (passed by -o
|
|
||||||
option) is hashed to an object ID that is used as the array oid.
|
|
||||||
|
|
||||||
The DFS (DAOS File System) driver creates an encapsulated namespace and emulates
|
The DFS (DAOS File System) driver creates an encapsulated namespace and emulates
|
||||||
the POSIX driver using the DFS API directly on top of DAOS. The DFS driver works
|
the POSIX driver using the DFS API directly on top of DAOS. The DFS driver works
|
||||||
with both IOR and mdtest.
|
with both IOR and mdtest.
|
||||||
|
|
||||||
Running with DAOS API
|
Running
|
||||||
---------------------
|
|
||||||
|
|
||||||
ior -a DAOS [ior_options] [daos_options]
|
|
||||||
|
|
||||||
In the IOR options, the file name should be specified as a container uuid using
|
|
||||||
"-o <container_uuid>". If the "-E" option is given, then this UUID shall denote
|
|
||||||
an existing container created by a "matching" IOR run. Otherwise, IOR will
|
|
||||||
create a new container with this UUID. In the latter case, one may use
|
|
||||||
uuidgen(1) to generate the UUID of the new container.
|
|
||||||
|
|
||||||
The DAOS options include:
|
|
||||||
|
|
||||||
Required Options:
|
|
||||||
--daos.pool <pool_uuid>: pool uuid to connect to (has to be created beforehand)
|
|
||||||
--daos.svcl <pool_svcl>: pool svcl list (: separated)
|
|
||||||
--daos.cont <cont_uuid>: container for the IOR files/objects (can use `uuidgen`)
|
|
||||||
|
|
||||||
Optional Options:
|
|
||||||
--daos.group <group_name>: group name of servers with the pool
|
|
||||||
--daos.chunk_size <chunk_size>: Chunk size of the array object controlling striping over DKEYs
|
|
||||||
--daos.destroy flag to destroy the container on finalize
|
|
||||||
--daos.oclass <object_class>: specific object class for array object
|
|
||||||
|
|
||||||
Examples that should work include:
|
|
||||||
|
|
||||||
- "ior -a DAOS -w -W -o file_name --daos.pool <pool_uuid> --daos.svcl <svc_ranks>\
|
|
||||||
--daos.cont <cont_uuid>"
|
|
||||||
|
|
||||||
- "ior -a DAOS -w -W -r -R -o file_name -b 1g -t 4m \
|
|
||||||
--daos.pool <pool_uuid> --daos.svcl <svc_ranks> --daos.cont <cont_uuid>\
|
|
||||||
--daos.chunk_size 1024 --daos.oclass R2"
|
|
||||||
|
|
||||||
Running with DFS API
|
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
ior -a DFS [ior_options] [dfs_options]
|
ior -a DFS [ior_options] [dfs_options]
|
||||||
|
@ -64,15 +22,17 @@ Required Options:
|
||||||
--dfs.cont <co_uuid>: container uuid that will hold the encapsulated namespace
|
--dfs.cont <co_uuid>: container uuid that will hold the encapsulated namespace
|
||||||
|
|
||||||
Optional Options:
|
Optional Options:
|
||||||
--dfs.group <group_name>: group name of servers with the pool
|
--dfs.group <group_name>: group name of servers with the pool (default: daos_server)
|
||||||
--dfs.chunk_size <chunk_size>: Chunk size of the files
|
--dfs.chunk_size <chunk_size>: Chunk size of the files (default: 1MiB)
|
||||||
--dfs.destroy flag to destroy the container on finalize
|
--dfs.destroy: flag to destroy the container on finalize (default: no)
|
||||||
--dfs.oclass <object_class>: specific object class for files
|
--dfs.oclass <object_class>: specific object class for files (default: SX)
|
||||||
|
--dfs.dir_oclass <object_class>: specific object class for directories (default: SX)
|
||||||
|
--dfs.prefix <path>: absolute path to account for DFS files/dirs before the cont root
|
||||||
|
|
||||||
In the IOR options, the file name should be specified on the root dir directly
|
If prefix is not set, in the IOR options, the file name should be specified on
|
||||||
since ior does not create directories and the DFS container representing the
|
the root dir directly since ior does not create directories and the DFS
|
||||||
encapsulated namespace is not the same as the system namespace the user is
|
container representing the encapsulated namespace is not the same as the system
|
||||||
executing from.
|
namespace the user is executing from.
|
||||||
|
|
||||||
Examples that should work include:
|
Examples that should work include:
|
||||||
- "ior -a DFS -w -W -o /test1 --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
- "ior -a DFS -w -W -o /test1 --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
||||||
|
@ -80,7 +40,8 @@ Examples that should work include:
|
||||||
- "ior -a DFS -w -r -o /test3 -b 8g -t 1m -C --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
- "ior -a DFS -w -r -o /test3 -b 8g -t 1m -C --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
||||||
|
|
||||||
Running mdtest, the user needs to specify a directory with -d where the test
|
Running mdtest, the user needs to specify a directory with -d where the test
|
||||||
tree will be created. Some examples:
|
tree will be created (set '/' if writing to the root of the DFS container). Some
|
||||||
- "mdtest -a DFS -n 100 -F -D -d /bla --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
examples:
|
||||||
- "mdtest -a DFS -n 1000 -F -C -d /bla --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
- "mdtest -a DFS -n 100 -F -D -d / --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
||||||
- "mdtest -a DFS -I 10 -z 5 -b 2 -L -d /bla --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
- "mdtest -a DFS -n 1000 -F -C -d / --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
||||||
|
- "mdtest -a DFS -I 10 -z 5 -b 2 -L -d / --dfs.pool <pool_uuid> --dfs.svcl <svc_ranks> --dfs.cont <co_uuid>"
|
||||||
|
|
26
configure.ac
26
configure.ac
|
@ -239,40 +239,26 @@ AM_COND_IF([USE_CEPHFS_AIORI],[
|
||||||
AC_DEFINE([USE_CEPHFS_AIORI], [], [Build CEPHFS backend AIORI])
|
AC_DEFINE([USE_CEPHFS_AIORI], [], [Build CEPHFS backend AIORI])
|
||||||
])
|
])
|
||||||
|
|
||||||
# DAOS Backends (DAOS and DFS) IO support require DAOS and CART/GURT
|
# DAOS-FS Backend (DFS)
|
||||||
AC_ARG_WITH([cart],
|
|
||||||
[AS_HELP_STRING([--with-cart],
|
|
||||||
[support IO with DAOS backends @<:@default=no@:>@])],
|
|
||||||
[], [with_daos=no])
|
|
||||||
|
|
||||||
AS_IF([test "x$with_cart" != xno], [
|
|
||||||
CART="yes"
|
|
||||||
LDFLAGS="$LDFLAGS -L$with_cart/lib64 -Wl,--enable-new-dtags -Wl,-rpath=$with_cart/lib64"
|
|
||||||
LDFLAGS="$LDFLAGS -L$with_cart/lib -Wl,--enable-new-dtags -Wl,-rpath=$with_cart/lib"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I$with_cart/include/"
|
|
||||||
AC_CHECK_HEADERS(gurt/common.h,, [unset CART])
|
|
||||||
AC_CHECK_LIB([gurt], [d_hash_murmur64],, [unset CART])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_ARG_WITH([daos],
|
AC_ARG_WITH([daos],
|
||||||
[AS_HELP_STRING([--with-daos],
|
[AS_HELP_STRING([--with-daos],
|
||||||
[support IO with DAOS backends @<:@default=no@:>@])],
|
[support IO with DAOS backend @<:@default=no@:>@])],
|
||||||
[], [with_daos=no])
|
[], [with_daos=no])
|
||||||
|
|
||||||
AS_IF([test "x$with_daos" != xno], [
|
AS_IF([test "x$with_daos" != xno], [
|
||||||
DAOS="yes"
|
DAOS="yes"
|
||||||
LDFLAGS="$LDFLAGS -L$with_daos/lib64 -Wl,--enable-new-dtags -Wl,-rpath=$with_daos/lib64"
|
LDFLAGS="$LDFLAGS -L$with_daos/lib64 -Wl,--enable-new-dtags -Wl,-rpath=$with_daos/lib64"
|
||||||
CPPFLAGS="$CPPFLAGS -I$with_daos/include"
|
CPPFLAGS="$CPPFLAGS -I$with_daos/include"
|
||||||
AC_CHECK_HEADERS(daos_types.h,, [unset DAOS])
|
AC_CHECK_HEADERS(gurt/common.h,, [unset DAOS])
|
||||||
|
AC_CHECK_HEADERS(daos.h,, [unset DAOS])
|
||||||
|
AC_CHECK_LIB([gurt], [d_hash_murmur64],, [unset DAOS])
|
||||||
AC_CHECK_LIB([uuid], [uuid_generate],, [unset DAOS])
|
AC_CHECK_LIB([uuid], [uuid_generate],, [unset DAOS])
|
||||||
AC_CHECK_LIB([daos_common], [daos_sgl_init],, [unset DAOS])
|
AC_CHECK_LIB([daos_common], [daos_sgl_init],, [unset DAOS])
|
||||||
AC_CHECK_LIB([daos], [daos_init],, [unset DAOS])
|
AC_CHECK_LIB([daos], [daos_init],, [unset DAOS])
|
||||||
AC_CHECK_LIB([dfs], [dfs_mkdir],, [unset DAOS])
|
AC_CHECK_LIB([dfs], [dfs_mkdir],, [unset DAOS])
|
||||||
])
|
])
|
||||||
|
|
||||||
AM_CONDITIONAL([USE_DAOS_AIORI], [test x$DAOS = xyes])
|
AM_CONDITIONAL([USE_DAOS_AIORI], [test x$DAOS = xyes])
|
||||||
AM_COND_IF([USE_DAOS_AIORI],[
|
AM_COND_IF([USE_DAOS_AIORI],[
|
||||||
AC_DEFINE([USE_DAOS_AIORI], [], [Build DAOS backends AIORI])
|
AC_DEFINE([USE_DAOS_AIORI], [], [Build DAOS-FS backend AIORI])
|
||||||
])
|
])
|
||||||
|
|
||||||
# Gfarm support
|
# Gfarm support
|
||||||
|
|
|
@ -87,7 +87,8 @@ endif
|
||||||
|
|
||||||
|
|
||||||
if USE_DAOS_AIORI
|
if USE_DAOS_AIORI
|
||||||
extraSOURCES += aiori-DAOS.c aiori-DFS.c
|
extraSOURCES += aiori-DFS.c
|
||||||
|
extraLDADD += -lgurt -ldaos_common -ldaos -ldfs -luuid
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_GFARM_AIORI
|
if USE_GFARM_AIORI
|
||||||
|
|
570
src/aiori-DAOS.c
570
src/aiori-DAOS.c
|
@ -1,570 +0,0 @@
|
||||||
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
||||||
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2018-2020 Intel Corporation
|
|
||||||
* See the file COPYRIGHT for a complete copyright notice and license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file implements the abstract I/O interface for DAOS Array API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _BSD_SOURCE
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <mpi.h>
|
|
||||||
#include <gurt/common.h>
|
|
||||||
#include <daos.h>
|
|
||||||
|
|
||||||
#include "aiori.h"
|
|
||||||
#include "utilities.h"
|
|
||||||
#include "iordef.h"
|
|
||||||
|
|
||||||
/************************** O P T I O N S *****************************/
|
|
||||||
typedef struct {
|
|
||||||
char *pool;
|
|
||||||
char *svcl;
|
|
||||||
char *group;
|
|
||||||
char *cont;
|
|
||||||
int chunk_size;
|
|
||||||
int destroy;
|
|
||||||
char *oclass;
|
|
||||||
} DAOS_options_t;
|
|
||||||
|
|
||||||
static option_help * DAOS_options(aiori_mod_opt_t ** init_backend_options,
|
|
||||||
aiori_mod_opt_t * init_values){
|
|
||||||
DAOS_options_t * o = malloc(sizeof(DAOS_options_t));
|
|
||||||
|
|
||||||
if (init_values != NULL) {
|
|
||||||
memcpy(o, init_values, sizeof(DAOS_options_t));
|
|
||||||
} else {
|
|
||||||
memset(o, 0, sizeof(DAOS_options_t));
|
|
||||||
/* initialize the options properly */
|
|
||||||
o->chunk_size = 1048576;
|
|
||||||
}
|
|
||||||
|
|
||||||
*init_backend_options = (aiori_mod_opt_t *) o;
|
|
||||||
|
|
||||||
option_help h [] = {
|
|
||||||
{0, "daos.pool", "pool uuid", OPTION_OPTIONAL_ARGUMENT, 's', &o->pool},
|
|
||||||
{0, "daos.svcl", "pool SVCL", OPTION_OPTIONAL_ARGUMENT, 's', &o->svcl},
|
|
||||||
{0, "daos.group", "server group", OPTION_OPTIONAL_ARGUMENT, 's', &o->group},
|
|
||||||
{0, "daos.cont", "container uuid", OPTION_OPTIONAL_ARGUMENT, 's', &o->cont},
|
|
||||||
{0, "daos.chunk_size", "chunk size", OPTION_OPTIONAL_ARGUMENT, 'd', &o->chunk_size},
|
|
||||||
{0, "daos.destroy", "Destroy Container", OPTION_FLAG, 'd', &o->destroy},
|
|
||||||
{0, "daos.oclass", "object class", OPTION_OPTIONAL_ARGUMENT, 's', &o->oclass},
|
|
||||||
LAST_OPTION
|
|
||||||
};
|
|
||||||
|
|
||||||
option_help * help = malloc(sizeof(h));
|
|
||||||
memcpy(help, h, sizeof(h));
|
|
||||||
return help;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************** P R O T O T Y P E S *****************************/
|
|
||||||
|
|
||||||
static void DAOS_Init(aiori_mod_opt_t *);
|
|
||||||
static void DAOS_Fini(aiori_mod_opt_t *);
|
|
||||||
static aiori_fd_t *DAOS_Create(char *, int, aiori_mod_opt_t *);
|
|
||||||
static aiori_fd_t *DAOS_Open(char *, int, aiori_mod_opt_t *);
|
|
||||||
static int DAOS_Access(const char *, int, aiori_mod_opt_t *);
|
|
||||||
static IOR_offset_t DAOS_Xfer(int, aiori_fd_t *, IOR_size_t *, IOR_offset_t,
|
|
||||||
IOR_offset_t, aiori_mod_opt_t *);
|
|
||||||
static void DAOS_Close(aiori_fd_t *, aiori_mod_opt_t *);
|
|
||||||
static void DAOS_Delete(char *, aiori_mod_opt_t *);
|
|
||||||
static char* DAOS_GetVersion();
|
|
||||||
static void DAOS_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
|
|
||||||
static IOR_offset_t DAOS_GetFileSize(aiori_mod_opt_t *, char *);
|
|
||||||
static option_help * DAOS_options();
|
|
||||||
static void DAOS_init_xfer_options(aiori_xfer_hint_t *);
|
|
||||||
static int DAOS_check_params(aiori_mod_opt_t *);
|
|
||||||
|
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
|
||||||
|
|
||||||
ior_aiori_t daos_aiori = {
|
|
||||||
.name = "DAOS",
|
|
||||||
.initialize = DAOS_Init,
|
|
||||||
.finalize = DAOS_Fini,
|
|
||||||
.create = DAOS_Create,
|
|
||||||
.open = DAOS_Open,
|
|
||||||
.access = DAOS_Access,
|
|
||||||
.xfer = DAOS_Xfer,
|
|
||||||
.close = DAOS_Close,
|
|
||||||
.delete = DAOS_Delete,
|
|
||||||
.get_version = DAOS_GetVersion,
|
|
||||||
.xfer_hints = DAOS_init_xfer_options,
|
|
||||||
.fsync = DAOS_Fsync,
|
|
||||||
.get_file_size = DAOS_GetFileSize,
|
|
||||||
.statfs = aiori_posix_statfs,
|
|
||||||
.mkdir = aiori_posix_mkdir,
|
|
||||||
.rmdir = aiori_posix_rmdir,
|
|
||||||
.stat = aiori_posix_stat,
|
|
||||||
.get_options = DAOS_options,
|
|
||||||
.xfer_hints = DAOS_init_xfer_options,
|
|
||||||
.check_params = DAOS_check_params,
|
|
||||||
.enable_mdtest = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IOR_DAOS_MUR_SEED 0xDEAD10CC
|
|
||||||
|
|
||||||
enum handleType {
|
|
||||||
POOL_HANDLE,
|
|
||||||
CONT_HANDLE,
|
|
||||||
ARRAY_HANDLE
|
|
||||||
};
|
|
||||||
|
|
||||||
static daos_handle_t poh;
|
|
||||||
static daos_handle_t coh;
|
|
||||||
static daos_handle_t aoh;
|
|
||||||
static daos_oclass_id_t objectClass = OC_SX;
|
|
||||||
static bool daos_initialized = false;
|
|
||||||
|
|
||||||
/***************************** F U N C T I O N S ******************************/
|
|
||||||
|
|
||||||
/* For DAOS methods. */
|
|
||||||
#define DCHECK(rc, format, ...) \
|
|
||||||
do { \
|
|
||||||
int _rc = (rc); \
|
|
||||||
\
|
|
||||||
if (_rc < 0) { \
|
|
||||||
fprintf(stderr, "ior ERROR (%s:%d): %d: %d: " \
|
|
||||||
format"\n", __FILE__, __LINE__, rank, _rc, \
|
|
||||||
##__VA_ARGS__); \
|
|
||||||
fflush(stdout); \
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, -1); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define INFO(level, format, ...) \
|
|
||||||
do { \
|
|
||||||
if (verbose >= level) \
|
|
||||||
printf("[%d] "format"\n", rank, ##__VA_ARGS__); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* For generic errors like invalid command line options. */
|
|
||||||
#define GERR(format, ...) \
|
|
||||||
do { \
|
|
||||||
fprintf(stderr, format"\n", ##__VA_ARGS__); \
|
|
||||||
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static aiori_xfer_hint_t * hints = NULL;
|
|
||||||
|
|
||||||
void DAOS_init_xfer_options(aiori_xfer_hint_t * params)
|
|
||||||
{
|
|
||||||
hints = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int DAOS_check_params(aiori_mod_opt_t * options){
|
|
||||||
DAOS_options_t *o = (DAOS_options_t *) options;
|
|
||||||
|
|
||||||
if (o->pool == NULL || o->svcl == NULL || o->cont == NULL)
|
|
||||||
ERR("Invalid pool or container options\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Distribute process 0's pool or container handle to others. */
|
|
||||||
static void
|
|
||||||
HandleDistribute(daos_handle_t *handle, enum handleType type)
|
|
||||||
{
|
|
||||||
d_iov_t global;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
global.iov_buf = NULL;
|
|
||||||
global.iov_buf_len = 0;
|
|
||||||
global.iov_len = 0;
|
|
||||||
|
|
||||||
if (rank == 0) {
|
|
||||||
/* Get the global handle size. */
|
|
||||||
if (type == POOL_HANDLE)
|
|
||||||
rc = daos_pool_local2global(*handle, &global);
|
|
||||||
else if (type == CONT_HANDLE)
|
|
||||||
rc = daos_cont_local2global(*handle, &global);
|
|
||||||
else
|
|
||||||
rc = daos_array_local2global(*handle, &global);
|
|
||||||
DCHECK(rc, "Failed to get global handle size");
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_Bcast(&global.iov_buf_len, 1, MPI_UINT64_T, 0,
|
|
||||||
MPI_COMM_WORLD),
|
|
||||||
"Failed to bcast global handle buffer size");
|
|
||||||
|
|
||||||
global.iov_len = global.iov_buf_len;
|
|
||||||
global.iov_buf = malloc(global.iov_buf_len);
|
|
||||||
if (global.iov_buf == NULL)
|
|
||||||
ERR("Failed to allocate global handle buffer");
|
|
||||||
|
|
||||||
if (rank == 0) {
|
|
||||||
if (type == POOL_HANDLE)
|
|
||||||
rc = daos_pool_local2global(*handle, &global);
|
|
||||||
else if (type == CONT_HANDLE)
|
|
||||||
rc = daos_cont_local2global(*handle, &global);
|
|
||||||
else
|
|
||||||
rc = daos_array_local2global(*handle, &global);
|
|
||||||
DCHECK(rc, "Failed to create global handle");
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_Bcast(global.iov_buf, global.iov_buf_len, MPI_BYTE, 0,
|
|
||||||
MPI_COMM_WORLD),
|
|
||||||
"Failed to bcast global pool handle");
|
|
||||||
|
|
||||||
if (rank != 0) {
|
|
||||||
if (type == POOL_HANDLE)
|
|
||||||
rc = daos_pool_global2local(global, handle);
|
|
||||||
else if (type == CONT_HANDLE)
|
|
||||||
rc = daos_cont_global2local(poh, global, handle);
|
|
||||||
else
|
|
||||||
rc = daos_array_global2local(coh, global, 0, handle);
|
|
||||||
DCHECK(rc, "Failed to get local handle");
|
|
||||||
}
|
|
||||||
|
|
||||||
free(global.iov_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DAOS_Init(aiori_mod_opt_t * options)
|
|
||||||
{
|
|
||||||
DAOS_options_t *o = (DAOS_options_t *)options;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (daos_initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (o->pool == NULL || o->svcl == NULL || o->cont == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (o->oclass) {
|
|
||||||
objectClass = daos_oclass_name2id(o->oclass);
|
|
||||||
if (objectClass == OC_UNKNOWN)
|
|
||||||
GERR("Invalid DAOS Object class %s\n", o->oclass);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = daos_init();
|
|
||||||
if (rc)
|
|
||||||
DCHECK(rc, "Failed to initialize daos");
|
|
||||||
|
|
||||||
if (rank == 0) {
|
|
||||||
uuid_t uuid;
|
|
||||||
d_rank_list_t *svcl = NULL;
|
|
||||||
static daos_pool_info_t po_info;
|
|
||||||
static daos_cont_info_t co_info;
|
|
||||||
|
|
||||||
INFO(VERBOSE_1, "Connecting to pool %s", o->pool);
|
|
||||||
|
|
||||||
rc = uuid_parse(o->pool, uuid);
|
|
||||||
DCHECK(rc, "Failed to parse 'pool': %s", o->pool);
|
|
||||||
|
|
||||||
svcl = daos_rank_list_parse(o->svcl, ":");
|
|
||||||
if (svcl == NULL)
|
|
||||||
ERR("Failed to allocate svcl");
|
|
||||||
|
|
||||||
rc = daos_pool_connect(uuid, o->group, svcl, DAOS_PC_RW,
|
|
||||||
&poh, &po_info, NULL);
|
|
||||||
d_rank_list_free(svcl);
|
|
||||||
DCHECK(rc, "Failed to connect to pool %s", o->pool);
|
|
||||||
|
|
||||||
INFO(VERBOSE_1, "Create/Open Container %s", o->cont);
|
|
||||||
|
|
||||||
uuid_clear(uuid);
|
|
||||||
rc = uuid_parse(o->cont, uuid);
|
|
||||||
DCHECK(rc, "Failed to parse 'cont': %s", o->cont);
|
|
||||||
|
|
||||||
rc = daos_cont_open(poh, uuid, DAOS_COO_RW, &coh, &co_info,
|
|
||||||
NULL);
|
|
||||||
/* If NOEXIST we create it */
|
|
||||||
if (rc == -DER_NONEXIST) {
|
|
||||||
INFO(VERBOSE_2, "Creating DAOS Container...\n");
|
|
||||||
rc = daos_cont_create(poh, uuid, NULL, NULL);
|
|
||||||
if (rc == 0)
|
|
||||||
rc = daos_cont_open(poh, uuid, DAOS_COO_RW,
|
|
||||||
&coh, &co_info, NULL);
|
|
||||||
}
|
|
||||||
DCHECK(rc, "Failed to create container");
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleDistribute(&poh, POOL_HANDLE);
|
|
||||||
HandleDistribute(&coh, CONT_HANDLE);
|
|
||||||
aoh.cookie = 0;
|
|
||||||
|
|
||||||
daos_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DAOS_Fini(aiori_mod_opt_t *options)
|
|
||||||
{
|
|
||||||
DAOS_options_t *o = (DAOS_options_t *)options;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!daos_initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MPI_Barrier(MPI_COMM_WORLD);
|
|
||||||
rc = daos_cont_close(coh, NULL);
|
|
||||||
if (rc) {
|
|
||||||
DCHECK(rc, "Failed to close container %s (%d)", o->cont, rc);
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
||||||
}
|
|
||||||
MPI_Barrier(MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
if (o->destroy) {
|
|
||||||
if (rank == 0) {
|
|
||||||
uuid_t uuid;
|
|
||||||
double t1, t2;
|
|
||||||
|
|
||||||
INFO(VERBOSE_1, "Destroying DAOS Container %s", o->cont);
|
|
||||||
uuid_parse(o->cont, uuid);
|
|
||||||
t1 = MPI_Wtime();
|
|
||||||
rc = daos_cont_destroy(poh, uuid, 1, NULL);
|
|
||||||
t2 = MPI_Wtime();
|
|
||||||
if (rc == 0)
|
|
||||||
INFO(VERBOSE_1, "Container Destroy time = %f secs", t2-t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Bcast(&rc, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
||||||
if (rc) {
|
|
||||||
if (rank == 0)
|
|
||||||
DCHECK(rc, "Failed to destroy container %s (%d)", o->cont, rc);
|
|
||||||
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rank == 0)
|
|
||||||
INFO(VERBOSE_1, "Disconnecting from DAOS POOL..");
|
|
||||||
|
|
||||||
rc = daos_pool_disconnect(poh, NULL);
|
|
||||||
DCHECK(rc, "Failed to disconnect from pool %s", o->pool);
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error");
|
|
||||||
if (rank == 0)
|
|
||||||
INFO(VERBOSE_1, "Finalizing DAOS..");
|
|
||||||
|
|
||||||
rc = daos_fini();
|
|
||||||
DCHECK(rc, "Failed to finalize daos");
|
|
||||||
|
|
||||||
daos_initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gen_oid(const char *name, daos_obj_id_t *oid)
|
|
||||||
{
|
|
||||||
oid->lo = d_hash_murmur64(name, strlen(name), IOR_DAOS_MUR_SEED);
|
|
||||||
oid->hi = 0;
|
|
||||||
|
|
||||||
daos_array_generate_id(oid, objectClass, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static aiori_fd_t *
|
|
||||||
DAOS_Create(char *testFileName, int flags, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
DAOS_options_t *o = (DAOS_options_t*) param;
|
|
||||||
daos_obj_id_t oid;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/** Convert file name into object ID */
|
|
||||||
gen_oid(testFileName, &oid);
|
|
||||||
|
|
||||||
/** Create the array */
|
|
||||||
if (hints->filePerProc || rank == 0) {
|
|
||||||
rc = daos_array_create(coh, oid, DAOS_TX_NONE, 1, o->chunk_size,
|
|
||||||
&aoh, NULL);
|
|
||||||
DCHECK(rc, "Failed to create array object\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Distribute the array handle if not FPP */
|
|
||||||
if (!hints->filePerProc)
|
|
||||||
HandleDistribute(&aoh, ARRAY_HANDLE);
|
|
||||||
|
|
||||||
return (aiori_fd_t*)(&aoh);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
DAOS_Access(const char *testFileName, int mode, aiori_mod_opt_t * param)
|
|
||||||
{
|
|
||||||
daos_obj_id_t oid;
|
|
||||||
daos_size_t cell_size, chunk_size;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/** Convert file name into object ID */
|
|
||||||
gen_oid(testFileName, &oid);
|
|
||||||
|
|
||||||
rc = daos_array_open(coh, oid, DAOS_TX_NONE, DAOS_OO_RO,
|
|
||||||
&cell_size, &chunk_size, &aoh, NULL);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if (cell_size != 1)
|
|
||||||
GERR("Invalid DAOS Array object.\n");
|
|
||||||
|
|
||||||
rc = daos_array_close(aoh, NULL);
|
|
||||||
aoh.cookie = 0;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static aiori_fd_t *
|
|
||||||
DAOS_Open(char *testFileName, int flags, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
daos_obj_id_t oid;
|
|
||||||
|
|
||||||
/** Convert file name into object ID */
|
|
||||||
gen_oid(testFileName, &oid);
|
|
||||||
|
|
||||||
/** Open the array */
|
|
||||||
if (hints->filePerProc || rank == 0) {
|
|
||||||
daos_size_t cell_size, chunk_size;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = daos_array_open(coh, oid, DAOS_TX_NONE, DAOS_OO_RW,
|
|
||||||
&cell_size, &chunk_size, &aoh, NULL);
|
|
||||||
DCHECK(rc, "Failed to create array object\n");
|
|
||||||
|
|
||||||
if (cell_size != 1)
|
|
||||||
GERR("Invalid DAOS Array object.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Distribute the array handle if not FPP */
|
|
||||||
if (!hints->filePerProc)
|
|
||||||
HandleDistribute(&aoh, ARRAY_HANDLE);
|
|
||||||
|
|
||||||
return (aiori_fd_t*)(&aoh);
|
|
||||||
}
|
|
||||||
|
|
||||||
static IOR_offset_t
|
|
||||||
DAOS_Xfer(int access, aiori_fd_t *file, IOR_size_t *buffer, IOR_offset_t length,
|
|
||||||
IOR_offset_t off, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
daos_array_iod_t iod;
|
|
||||||
daos_range_t rg;
|
|
||||||
d_sg_list_t sgl;
|
|
||||||
d_iov_t iov;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/** set array location */
|
|
||||||
iod.arr_nr = 1;
|
|
||||||
rg.rg_len = length;
|
|
||||||
rg.rg_idx = off;
|
|
||||||
iod.arr_rgs = &rg;
|
|
||||||
|
|
||||||
/** set memory location */
|
|
||||||
sgl.sg_nr = 1;
|
|
||||||
d_iov_set(&iov, buffer, length);
|
|
||||||
sgl.sg_iovs = &iov;
|
|
||||||
|
|
||||||
if (access == WRITE) {
|
|
||||||
rc = daos_array_write(aoh, DAOS_TX_NONE, &iod, &sgl, NULL);
|
|
||||||
DCHECK(rc, "daos_array_write() failed (%d).", rc);
|
|
||||||
} else {
|
|
||||||
rc = daos_array_read(aoh, DAOS_TX_NONE, &iod, &sgl, NULL);
|
|
||||||
DCHECK(rc, "daos_array_read() failed (%d).", rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DAOS_Close(aiori_fd_t *file, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!daos_initialized)
|
|
||||||
GERR("DAOS is not initialized!");
|
|
||||||
|
|
||||||
rc = daos_array_close(aoh, NULL);
|
|
||||||
DCHECK(rc, "daos_array_close() failed (%d).", rc);
|
|
||||||
|
|
||||||
aoh.cookie = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DAOS_Delete(char *testFileName, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
daos_obj_id_t oid;
|
|
||||||
daos_size_t cell_size, chunk_size;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!daos_initialized)
|
|
||||||
GERR("DAOS is not initialized!");
|
|
||||||
|
|
||||||
/** Convert file name into object ID */
|
|
||||||
gen_oid(testFileName, &oid);
|
|
||||||
|
|
||||||
/** open the array to verify it exists */
|
|
||||||
rc = daos_array_open(coh, oid, DAOS_TX_NONE, DAOS_OO_RW,
|
|
||||||
&cell_size, &chunk_size, &aoh, NULL);
|
|
||||||
DCHECK(rc, "daos_array_open() failed (%d).", rc);
|
|
||||||
|
|
||||||
if (cell_size != 1)
|
|
||||||
GERR("Invalid DAOS Array object.\n");
|
|
||||||
|
|
||||||
rc = daos_array_destroy(aoh, DAOS_TX_NONE, NULL);
|
|
||||||
DCHECK(rc, "daos_array_destroy() failed (%d).", rc);
|
|
||||||
|
|
||||||
rc = daos_array_close(aoh, NULL);
|
|
||||||
DCHECK(rc, "daos_array_close() failed (%d).", rc);
|
|
||||||
aoh.cookie = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
DAOS_GetVersion()
|
|
||||||
{
|
|
||||||
static char ver[1024] = {};
|
|
||||||
|
|
||||||
sprintf(ver, "%s", "DAOS");
|
|
||||||
return ver;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
DAOS_Fsync(aiori_fd_t *file, aiori_mod_opt_t *param)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IOR_offset_t
|
|
||||||
DAOS_GetFileSize(aiori_mod_opt_t *param, char *testFileName)
|
|
||||||
{
|
|
||||||
daos_obj_id_t oid;
|
|
||||||
daos_size_t size;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (!daos_initialized)
|
|
||||||
GERR("DAOS is not initialized!");
|
|
||||||
|
|
||||||
/** Convert file name into object ID */
|
|
||||||
gen_oid(testFileName, &oid);
|
|
||||||
|
|
||||||
/** open the array to verify it exists */
|
|
||||||
if (hints->filePerProc || rank == 0) {
|
|
||||||
daos_size_t cell_size, chunk_size;
|
|
||||||
|
|
||||||
rc = daos_array_open(coh, oid, DAOS_TX_NONE, DAOS_OO_RO,
|
|
||||||
&cell_size, &chunk_size, &aoh, NULL);
|
|
||||||
DCHECK(rc, "daos_array_open() failed (%d).", rc);
|
|
||||||
|
|
||||||
if (cell_size != 1)
|
|
||||||
GERR("Invalid DAOS Array object.\n");
|
|
||||||
|
|
||||||
rc = daos_array_get_size(aoh, DAOS_TX_NONE, &size, NULL);
|
|
||||||
DCHECK(rc, "daos_array_get_size() failed (%d).", rc);
|
|
||||||
|
|
||||||
rc = daos_array_close(aoh, NULL);
|
|
||||||
DCHECK(rc, "daos_array_close() failed (%d).", rc);
|
|
||||||
aoh.cookie = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hints->filePerProc)
|
|
||||||
MPI_Bcast(&size, 1, MPI_LONG, 0, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
|
@ -777,21 +777,35 @@ static IOR_offset_t
|
||||||
DFS_GetFileSize(aiori_mod_opt_t * test, char *testFileName)
|
DFS_GetFileSize(aiori_mod_opt_t * test, char *testFileName)
|
||||||
{
|
{
|
||||||
dfs_obj_t *obj;
|
dfs_obj_t *obj;
|
||||||
daos_size_t fsize, tmpMin, tmpMax, tmpSum;
|
MPI_Comm comm;
|
||||||
|
daos_size_t fsize;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = dfs_lookup(dfs, testFileName, O_RDONLY, &obj, NULL, NULL);
|
if (hints->filePerProc == TRUE) {
|
||||||
if (rc) {
|
comm = MPI_COMM_SELF;
|
||||||
fprintf(stderr, "dfs_lookup() of %s Failed (%d)", testFileName, rc);
|
} else {
|
||||||
return -1;
|
comm = testComm;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = dfs_get_size(dfs, obj, &fsize);
|
if (hints->filePerProc || rank == 0) {
|
||||||
if (rc)
|
rc = dfs_lookup(dfs, testFileName, O_RDONLY, &obj, NULL, NULL);
|
||||||
return -1;
|
if (rc) {
|
||||||
|
fprintf(stderr, "dfs_lookup() of %s Failed (%d)", testFileName, rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
dfs_release(obj);
|
rc = dfs_get_size(dfs, obj, &fsize);
|
||||||
|
dfs_release(obj);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hints->filePerProc) {
|
||||||
|
rc = MPI_Bcast(&fsize, 1, MPI_UINT64_T, 0, comm);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
return (fsize);
|
return (fsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ ior_aiori_t *available_aiori[] = {
|
||||||
&pmdk_aiori,
|
&pmdk_aiori,
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DAOS_AIORI
|
#ifdef USE_DAOS_AIORI
|
||||||
&daos_aiori,
|
|
||||||
&dfs_aiori,
|
&dfs_aiori,
|
||||||
#endif
|
#endif
|
||||||
& dummy_aiori,
|
& dummy_aiori,
|
||||||
|
|
|
@ -349,8 +349,7 @@ static void CheckFileSize(IOR_test_t *test, char * testFilename, IOR_offset_t da
|
||||||
1, MPI_LONG_LONG_INT, MPI_SUM, testComm),
|
1, MPI_LONG_LONG_INT, MPI_SUM, testComm),
|
||||||
"cannot total data moved");
|
"cannot total data moved");
|
||||||
|
|
||||||
if (strcasecmp(params->api, "HDF5") != 0 && strcasecmp(params->api, "NCMPI") != 0 &&
|
if (strcasecmp(params->api, "HDF5") != 0 && strcasecmp(params->api, "NCMPI") != 0) {
|
||||||
strcasecmp(params->api, "DAOS") != 0) {
|
|
||||||
if (verbose >= VERBOSE_0 && rank == 0) {
|
if (verbose >= VERBOSE_0 && rank == 0) {
|
||||||
if ((params->expectedAggFileSize
|
if ((params->expectedAggFileSize
|
||||||
!= point->aggFileSizeFromXfer)
|
!= point->aggFileSizeFromXfer)
|
||||||
|
@ -1609,7 +1608,6 @@ static void ValidateTests(IOR_param_t * test)
|
||||||
&& (strcasecmp(test->api, "MMAP") != 0)
|
&& (strcasecmp(test->api, "MMAP") != 0)
|
||||||
&& (strcasecmp(test->api, "HDFS") != 0)
|
&& (strcasecmp(test->api, "HDFS") != 0)
|
||||||
&& (strcasecmp(test->api, "DFS") != 0)
|
&& (strcasecmp(test->api, "DFS") != 0)
|
||||||
&& (strcasecmp(test->api, "DAOS") != 0)
|
|
||||||
&& (strcasecmp(test->api, "Gfarm") != 0)
|
&& (strcasecmp(test->api, "Gfarm") != 0)
|
||||||
&& (strcasecmp(test->api, "RADOS") != 0)
|
&& (strcasecmp(test->api, "RADOS") != 0)
|
||||||
&& (strcasecmp(test->api, "CEPHFS") != 0)) && test->fsync)
|
&& (strcasecmp(test->api, "CEPHFS") != 0)) && test->fsync)
|
||||||
|
|
Loading…
Reference in New Issue