commit
0adc246adc
|
@ -4,6 +4,8 @@ Makefile.in
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
config.log
|
config.log
|
||||||
config.status
|
config.status
|
||||||
|
COPYING
|
||||||
|
INSTALL
|
||||||
config/compile
|
config/compile
|
||||||
config/config.guess
|
config/config.guess
|
||||||
config/config.sub
|
config/config.sub
|
||||||
|
@ -13,12 +15,14 @@ config/missing
|
||||||
config/test-driver
|
config/test-driver
|
||||||
configure
|
configure
|
||||||
contrib/.deps/
|
contrib/.deps/
|
||||||
|
contrib/cbif
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
contrib/Makefile.in
|
contrib/Makefile.in
|
||||||
contrib/cbif
|
contrib/cbif
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/Makefile.in
|
doc/Makefile.in
|
||||||
src/.deps/
|
src/.deps/
|
||||||
|
src/mdtest
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/Makefile.in
|
src/Makefile.in
|
||||||
src/config.h
|
src/config.h
|
||||||
|
|
28
configure.ac
28
configure.ac
|
@ -166,17 +166,27 @@ AM_COND_IF([USE_RADOS_AIORI],[
|
||||||
AC_DEFINE([USE_RADOS_AIORI], [], [Build RADOS backend AIORI])
|
AC_DEFINE([USE_RADOS_AIORI], [], [Build RADOS backend AIORI])
|
||||||
])
|
])
|
||||||
|
|
||||||
# DAOS support
|
# DAOS Backends (DAOS and DFS) IO support
|
||||||
AC_ARG_WITH([daos],
|
AC_ARG_WITH([daos],
|
||||||
[AS_HELP_STRING([--with-daos],
|
[AS_HELP_STRING([--with-daos],
|
||||||
[support IO with DAOS backend @<:@default=no@:>@])],
|
[support IO with DAOS backends @<:@default=no@:>@])],
|
||||||
[],
|
[],
|
||||||
[with_daos=no])
|
[with_daos=no])
|
||||||
AM_CONDITIONAL([USE_DAOS_AIORI], [test x$with_daos = xyes])
|
|
||||||
AM_COND_IF([USE_DAOS_AIORI],[
|
|
||||||
AC_DEFINE([USE_DAOS_AIORI], [], [Build DAOS backend AIORI])
|
|
||||||
])
|
|
||||||
|
|
||||||
|
AS_IF([test "x$with_daos" != xno],
|
||||||
|
DAOS="yes"
|
||||||
|
LDFLAGS="$LDFLAGS -L$with_daos/lib"
|
||||||
|
CPPFLAGS="$CPPFLAGS -I$with_daos/include"
|
||||||
|
AC_CHECK_HEADERS(daos_types.h,, [unset DAOS])
|
||||||
|
AC_CHECK_LIB([uuid], [uuid_generate],, [unset DAOS])
|
||||||
|
AC_CHECK_LIB([daos_common], [daos_sgl_init],, [unset DAOS])
|
||||||
|
AC_CHECK_LIB([daos], [daos_init],, [unset DAOS])
|
||||||
|
AC_CHECK_LIB([dfs], [dfs_mkdir],, [unset DAOS]))
|
||||||
|
|
||||||
|
AM_CONDITIONAL([USE_DAOS_AIORI], [test x$DAOS = xyes])
|
||||||
|
AM_COND_IF([USE_DAOS_AIORI],[
|
||||||
|
AC_DEFINE([USE_DAOS_AIORI], [], [Build DAOS backends AIORI])
|
||||||
|
])
|
||||||
|
|
||||||
# aws4c is needed for the S3 backend (see --with-S3, below).
|
# aws4c is needed for the S3 backend (see --with-S3, below).
|
||||||
# Version 0.5.2 of aws4c is available at https://github.com/jti-lanl/aws4c.git
|
# Version 0.5.2 of aws4c is available at https://github.com/jti-lanl/aws4c.git
|
||||||
|
|
|
@ -71,8 +71,7 @@ extraLDADD += -lrados
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_DAOS_AIORI
|
if USE_DAOS_AIORI
|
||||||
extraSOURCES += aiori-DAOS.c list.h
|
extraSOURCES += aiori-DAOS.c aiori-DFS.c list.h
|
||||||
extraLDADD += -ldaos -ldaos_common -luuid
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_S3_AIORI
|
if USE_S3_AIORI
|
||||||
|
|
191
src/aiori-DAOS.c
191
src/aiori-DAOS.c
|
@ -35,6 +35,56 @@
|
||||||
#include "iordef.h"
|
#include "iordef.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
|
/************************** O P T I O N S *****************************/
|
||||||
|
struct daos_options{
|
||||||
|
char *daosPool;
|
||||||
|
char *daosPoolSvc;
|
||||||
|
char *daosGroup;
|
||||||
|
int daosRecordSize;
|
||||||
|
int daosStripeSize;
|
||||||
|
uint64_t daosStripeCount;
|
||||||
|
uint64_t daosStripeMax; /* max length of a stripe */
|
||||||
|
int daosAios; /* max number of concurrent async I/Os */
|
||||||
|
int daosWriteOnly; /* write only, no flush and commit */
|
||||||
|
uint64_t daosEpoch; /* epoch to access */
|
||||||
|
uint64_t daosWait; /* epoch to wait for before reading */
|
||||||
|
int daosKill; /* kill a target while running IOR */
|
||||||
|
char *daosObjectClass; /* object class */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct daos_options o = {
|
||||||
|
.daosPool = NULL,
|
||||||
|
.daosPoolSvc = NULL,
|
||||||
|
.daosGroup = NULL,
|
||||||
|
.daosRecordSize = 262144,
|
||||||
|
.daosStripeSize = 524288,
|
||||||
|
.daosStripeCount = -1,
|
||||||
|
.daosStripeMax = 0,
|
||||||
|
.daosAios = 1,
|
||||||
|
.daosWriteOnly = 0,
|
||||||
|
.daosEpoch = 0,
|
||||||
|
.daosWait = 0,
|
||||||
|
.daosKill = 0,
|
||||||
|
.daosObjectClass = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static option_help options [] = {
|
||||||
|
{'p', "daosPool", "pool uuid", OPTION_REQUIRED_ARGUMENT, 's', &o.daosPool},
|
||||||
|
{'v', "daosPoolSvc", "pool SVCL", OPTION_REQUIRED_ARGUMENT, 's', &o.daosPoolSvc},
|
||||||
|
{'g', "daosGroup", "server group", OPTION_OPTIONAL_ARGUMENT, 's', &o.daosGroup},
|
||||||
|
{'r', "daosRecordSize", "Record Size", OPTION_OPTIONAL_ARGUMENT, 'd', &o.daosRecordSize},
|
||||||
|
{'s', "daosStripeSize", "Stripe Size", OPTION_OPTIONAL_ARGUMENT, 'd', &o.daosStripeSize},
|
||||||
|
{'c', "daosStripeCount", "Stripe Count", OPTION_OPTIONAL_ARGUMENT, 'u', &o.daosStripeCount},
|
||||||
|
{'m', "daosStripeMax", "Max Stripe",OPTION_OPTIONAL_ARGUMENT, 'u', &o.daosStripeMax},
|
||||||
|
{'a', "daosAios", "Concurrent Async IOs",OPTION_OPTIONAL_ARGUMENT, 'd', &o.daosAios},
|
||||||
|
{'w', "daosWriteOnly", "Write Only, no commit",OPTION_OPTIONAL_ARGUMENT, 'd', &o.daosWriteOnly},
|
||||||
|
{'e', "daosEpoch", "Epoch Number to Access",OPTION_OPTIONAL_ARGUMENT, 'u', &o.daosEpoch},
|
||||||
|
{'t', "daosWait", "Epoch to wait for before read",OPTION_OPTIONAL_ARGUMENT, 'u', &o.daosWait},
|
||||||
|
{'k', "daosKill", "Kill target while running",OPTION_OPTIONAL_ARGUMENT, 'd', &o.daosKill},
|
||||||
|
{'o', "daosObjectClass", "object class", OPTION_OPTIONAL_ARGUMENT, 's', &o.daosObjectClass},
|
||||||
|
LAST_OPTION
|
||||||
|
};
|
||||||
|
|
||||||
/**************************** P R O T O T Y P E S *****************************/
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
|
||||||
static void DAOS_Init(IOR_param_t *);
|
static void DAOS_Init(IOR_param_t *);
|
||||||
|
@ -48,21 +98,23 @@ static void DAOS_Delete(char *, IOR_param_t *);
|
||||||
static char* DAOS_GetVersion();
|
static char* DAOS_GetVersion();
|
||||||
static void DAOS_Fsync(void *, IOR_param_t *);
|
static void DAOS_Fsync(void *, IOR_param_t *);
|
||||||
static IOR_offset_t DAOS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
static IOR_offset_t DAOS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
|
static option_help * DAOS_options();
|
||||||
|
|
||||||
/************************** D E C L A R A T I O N S ***************************/
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
ior_aiori_t daos_aiori = {
|
ior_aiori_t daos_aiori = {
|
||||||
.name = "DAOS",
|
.name = "DAOS",
|
||||||
.create = DAOS_Create,
|
.create = DAOS_Create,
|
||||||
.open = DAOS_Open,
|
.open = DAOS_Open,
|
||||||
.xfer = DAOS_Xfer,
|
.xfer = DAOS_Xfer,
|
||||||
.close = DAOS_Close,
|
.close = DAOS_Close,
|
||||||
.delete = DAOS_Delete,
|
.delete = DAOS_Delete,
|
||||||
.get_version = DAOS_GetVersion,
|
.get_version = DAOS_GetVersion,
|
||||||
.fsync = DAOS_Fsync,
|
.fsync = DAOS_Fsync,
|
||||||
.get_file_size = DAOS_GetFileSize,
|
.get_file_size = DAOS_GetFileSize,
|
||||||
.initialize = DAOS_Init,
|
.initialize = DAOS_Init,
|
||||||
.finalize = DAOS_Fini,
|
.finalize = DAOS_Fini,
|
||||||
|
.get_options = DAOS_options,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum handleType {
|
enum handleType {
|
||||||
|
@ -234,10 +286,10 @@ static void ContainerOpen(char *testFileName, IOR_param_t *param,
|
||||||
info->ci_epoch_state.es_ghpce);
|
info->ci_epoch_state.es_ghpce);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (param->open != WRITE && param->daosWait != 0) {
|
if (param->open != WRITE && o.daosWait != 0) {
|
||||||
daos_epoch_t e;
|
daos_epoch_t e;
|
||||||
|
|
||||||
e = param->daosWait;
|
e = o.daosWait;
|
||||||
|
|
||||||
INFO(VERBOSE_2, param, "Waiting for epoch %lu", e);
|
INFO(VERBOSE_2, param, "Waiting for epoch %lu", e);
|
||||||
|
|
||||||
|
@ -245,7 +297,7 @@ static void ContainerOpen(char *testFileName, IOR_param_t *param,
|
||||||
NULL /* ignore HLE */,
|
NULL /* ignore HLE */,
|
||||||
NULL /* synchronous */);
|
NULL /* synchronous */);
|
||||||
DCHECK(rc, "Failed to wait for epoch %lu",
|
DCHECK(rc, "Failed to wait for epoch %lu",
|
||||||
param->daosWait);
|
o.daosWait);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->open == WRITE &&
|
if (param->open == WRITE &&
|
||||||
|
@ -345,10 +397,10 @@ static void AIOInit(IOR_param_t *param)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = posix_memalign((void **) &buffers, sysconf(_SC_PAGESIZE),
|
rc = posix_memalign((void **) &buffers, sysconf(_SC_PAGESIZE),
|
||||||
param->transferSize * param->daosAios);
|
param->transferSize * o.daosAios);
|
||||||
DCHECK(rc, "Failed to allocate buffer array");
|
DCHECK(rc, "Failed to allocate buffer array");
|
||||||
|
|
||||||
for (i = 0; i < param->daosAios; i++) {
|
for (i = 0; i < o.daosAios; i++) {
|
||||||
aio = malloc(sizeof *aio);
|
aio = malloc(sizeof *aio);
|
||||||
if (aio == NULL)
|
if (aio == NULL)
|
||||||
ERR("Failed to allocate aio array");
|
ERR("Failed to allocate aio array");
|
||||||
|
@ -394,9 +446,9 @@ static void AIOInit(IOR_param_t *param)
|
||||||
aio->a_iov.iov_buf);
|
aio->a_iov.iov_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
nAios = param->daosAios;
|
nAios = o.daosAios;
|
||||||
|
|
||||||
events = malloc((sizeof *events) * param->daosAios);
|
events = malloc((sizeof *events) * o.daosAios);
|
||||||
if (events == NULL)
|
if (events == NULL)
|
||||||
ERR("Failed to allocate events array");
|
ERR("Failed to allocate events array");
|
||||||
}
|
}
|
||||||
|
@ -425,10 +477,10 @@ static void AIOWait(IOR_param_t *param)
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = daos_eq_poll(eventQueue, 0, DAOS_EQ_WAIT, param->daosAios,
|
rc = daos_eq_poll(eventQueue, 0, DAOS_EQ_WAIT, o.daosAios,
|
||||||
events);
|
events);
|
||||||
DCHECK(rc, "Failed to poll event queue");
|
DCHECK(rc, "Failed to poll event queue");
|
||||||
assert(rc <= param->daosAios - nAios);
|
assert(rc <= o.daosAios - nAios);
|
||||||
|
|
||||||
for (i = 0; i < rc; i++) {
|
for (i = 0; i < rc; i++) {
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -455,7 +507,7 @@ static void AIOWait(IOR_param_t *param)
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO(VERBOSE_3, param, "Found %d completed AIOs (%d free %d busy)", rc,
|
INFO(VERBOSE_3, param, "Found %d completed AIOs (%d free %d busy)", rc,
|
||||||
nAios, param->daosAios - nAios);
|
nAios, o.daosAios - nAios);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ObjectClassParse(const char *string)
|
static void ObjectClassParse(const char *string)
|
||||||
|
@ -486,18 +538,11 @@ static void ObjectClassParse(const char *string)
|
||||||
GERR("Invalid 'daosObjectClass' argument: '%s'", string);
|
GERR("Invalid 'daosObjectClass' argument: '%s'", string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *GetGroup(IOR_param_t *param)
|
|
||||||
{
|
|
||||||
if (strlen(param->daosGroup) == 0)
|
|
||||||
return NULL;
|
|
||||||
return param->daosGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ParseService(IOR_param_t *param, int max, d_rank_list_t *ranks)
|
static void ParseService(IOR_param_t *param, int max, d_rank_list_t *ranks)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
s = strdup(param->daosPoolSvc);
|
s = strdup(o.daosPoolSvc);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
GERR("failed to duplicate argument");
|
GERR("failed to duplicate argument");
|
||||||
ranks->rl_nr = 0;
|
ranks->rl_nr = 0;
|
||||||
|
@ -513,22 +558,26 @@ static void ParseService(IOR_param_t *param, int max, d_rank_list_t *ranks)
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static option_help * DAOS_options(){
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
static void DAOS_Init(IOR_param_t *param)
|
static void DAOS_Init(IOR_param_t *param)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (strlen(param->daosObjectClass) != 0)
|
if (o.daosObjectClass)
|
||||||
ObjectClassParse(param->daosObjectClass);
|
ObjectClassParse(o.daosObjectClass);
|
||||||
|
|
||||||
if (param->filePerProc)
|
if (param->filePerProc)
|
||||||
GERR("'filePerProc' not yet supported");
|
GERR("'filePerProc' not yet supported");
|
||||||
if (param->daosStripeMax % param->daosStripeSize != 0)
|
if (o.daosStripeMax % o.daosStripeSize != 0)
|
||||||
GERR("'daosStripeMax' must be a multiple of 'daosStripeSize'");
|
GERR("'daosStripeMax' must be a multiple of 'daosStripeSize'");
|
||||||
if (param->daosStripeSize % param->transferSize != 0)
|
if (o.daosStripeSize % param->transferSize != 0)
|
||||||
GERR("'daosStripeSize' must be a multiple of 'transferSize'");
|
GERR("'daosStripeSize' must be a multiple of 'transferSize'");
|
||||||
if (param->transferSize % param->daosRecordSize != 0)
|
if (param->transferSize % o.daosRecordSize != 0)
|
||||||
GERR("'transferSize' must be a multiple of 'daosRecordSize'");
|
GERR("'transferSize' must be a multiple of 'daosRecordSize'");
|
||||||
if (param->daosKill && ((objectClass != DAOS_OC_R2_RW) ||
|
if (o.daosKill && ((objectClass != DAOS_OC_R2_RW) ||
|
||||||
(objectClass != DAOS_OC_R3_RW) ||
|
(objectClass != DAOS_OC_R3_RW) ||
|
||||||
(objectClass != DAOS_OC_R4_RW) ||
|
(objectClass != DAOS_OC_R4_RW) ||
|
||||||
(objectClass != DAOS_OC_R2S_RW) ||
|
(objectClass != DAOS_OC_R2S_RW) ||
|
||||||
|
@ -551,23 +600,23 @@ static void DAOS_Init(IOR_param_t *param)
|
||||||
d_rank_t rank[13];
|
d_rank_t rank[13];
|
||||||
d_rank_list_t ranks;
|
d_rank_list_t ranks;
|
||||||
|
|
||||||
if (strlen(param->daosPool) == 0)
|
if (o.daosPool == NULL)
|
||||||
GERR("'daosPool' must be specified");
|
GERR("'daosPool' must be specified");
|
||||||
if (strlen(param->daosPoolSvc) == 0)
|
if (o.daosPoolSvc == NULL)
|
||||||
GERR("'daosPoolSvc' must be specified");
|
GERR("'daosPoolSvc' must be specified");
|
||||||
|
|
||||||
INFO(VERBOSE_2, param, "Connecting to pool %s %s",
|
INFO(VERBOSE_2, param, "Connecting to pool %s %s",
|
||||||
param->daosPool, param->daosPoolSvc);
|
o.daosPool, o.daosPoolSvc);
|
||||||
|
|
||||||
rc = uuid_parse(param->daosPool, uuid);
|
rc = uuid_parse(o.daosPool, uuid);
|
||||||
DCHECK(rc, "Failed to parse 'daosPool': %s", param->daosPool);
|
DCHECK(rc, "Failed to parse 'daosPool': %s", o.daosPool);
|
||||||
ranks.rl_ranks = rank;
|
ranks.rl_ranks = rank;
|
||||||
ParseService(param, sizeof(rank) / sizeof(rank[0]), &ranks);
|
ParseService(param, sizeof(rank) / sizeof(rank[0]), &ranks);
|
||||||
|
|
||||||
rc = daos_pool_connect(uuid, GetGroup(param), &ranks,
|
rc = daos_pool_connect(uuid, o.daosGroup, &ranks,
|
||||||
DAOS_PC_RW, &pool, &poolInfo,
|
DAOS_PC_RW, &pool, &poolInfo,
|
||||||
NULL /* ev */);
|
NULL /* ev */);
|
||||||
DCHECK(rc, "Failed to connect to pool %s", param->daosPool);
|
DCHECK(rc, "Failed to connect to pool %s", o.daosPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleDistribute(&pool, POOL_HANDLE, param);
|
HandleDistribute(&pool, POOL_HANDLE, param);
|
||||||
|
@ -576,8 +625,8 @@ static void DAOS_Init(IOR_param_t *param)
|
||||||
param->testComm),
|
param->testComm),
|
||||||
"Failed to bcast pool info");
|
"Failed to bcast pool info");
|
||||||
|
|
||||||
if (param->daosStripeCount == -1)
|
if (o.daosStripeCount == -1)
|
||||||
param->daosStripeCount = poolInfo.pi_ntargets * 64UL;
|
o.daosStripeCount = poolInfo.pi_ntargets * 64UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DAOS_Fini(IOR_param_t *param)
|
static void DAOS_Fini(IOR_param_t *param)
|
||||||
|
@ -585,7 +634,7 @@ static void DAOS_Fini(IOR_param_t *param)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = daos_pool_disconnect(pool, NULL /* ev */);
|
rc = daos_pool_disconnect(pool, NULL /* ev */);
|
||||||
DCHECK(rc, "Failed to disconnect from pool %s", param->daosPool);
|
DCHECK(rc, "Failed to disconnect from pool %s", o.daosPool);
|
||||||
|
|
||||||
rc = daos_eq_destroy(eventQueue, 0 /* flags */);
|
rc = daos_eq_destroy(eventQueue, 0 /* flags */);
|
||||||
DCHECK(rc, "Failed to destroy event queue");
|
DCHECK(rc, "Failed to destroy event queue");
|
||||||
|
@ -612,22 +661,22 @@ static void *DAOS_Open(char *testFileName, IOR_param_t *param)
|
||||||
|
|
||||||
ghce = fd->containerInfo.ci_epoch_state.es_ghce;
|
ghce = fd->containerInfo.ci_epoch_state.es_ghce;
|
||||||
if (param->open == WRITE) {
|
if (param->open == WRITE) {
|
||||||
if (param->daosEpoch == 0)
|
if (o.daosEpoch == 0)
|
||||||
fd->epoch = ghce + 1;
|
fd->epoch = ghce + 1;
|
||||||
else if (param->daosEpoch <= ghce)
|
else if (o.daosEpoch <= ghce)
|
||||||
GERR("Can't modify committed epoch\n");
|
GERR("Can't modify committed epoch\n");
|
||||||
else
|
else
|
||||||
fd->epoch = param->daosEpoch;
|
fd->epoch = o.daosEpoch;
|
||||||
} else {
|
} else {
|
||||||
if (param->daosEpoch == 0) {
|
if (o.daosEpoch == 0) {
|
||||||
if (param->daosWait == 0)
|
if (o.daosWait == 0)
|
||||||
fd->epoch = ghce;
|
fd->epoch = ghce;
|
||||||
else
|
else
|
||||||
fd->epoch = param->daosWait;
|
fd->epoch = o.daosWait;
|
||||||
} else if (param->daosEpoch > ghce) {
|
} else if (o.daosEpoch > ghce) {
|
||||||
GERR("Can't read uncommitted epoch\n");
|
GERR("Can't read uncommitted epoch\n");
|
||||||
} else {
|
} else {
|
||||||
fd->epoch = param->daosEpoch;
|
fd->epoch = o.daosEpoch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,15 +720,15 @@ kill_daos_server(IOR_param_t *param)
|
||||||
/* choose the last alive one */
|
/* choose the last alive one */
|
||||||
rank = info.pi_ntargets - 1 - info.pi_ndisabled;
|
rank = info.pi_ntargets - 1 - info.pi_ndisabled;
|
||||||
|
|
||||||
rc = uuid_parse(param->daosPool, uuid);
|
rc = uuid_parse(o.daosPool, uuid);
|
||||||
DCHECK(rc, "Failed to parse 'daosPool': %s", param->daosPool);
|
DCHECK(rc, "Failed to parse 'daosPool': %s", o.daosPool);
|
||||||
|
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
printf("Killing tgt rank: %d (total of %d of %d already disabled)\n",
|
printf("Killing tgt rank: %d (total of %d of %d already disabled)\n",
|
||||||
rank, info.pi_ndisabled, info.pi_ntargets);
|
rank, info.pi_ndisabled, info.pi_ntargets);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
rc = daos_mgmt_svc_rip(GetGroup(param), rank, true, NULL);
|
rc = daos_mgmt_svc_rip(o.daosGroup, rank, true, NULL);
|
||||||
DCHECK(rc, "Error in killing server\n");
|
DCHECK(rc, "Error in killing server\n");
|
||||||
|
|
||||||
targets.rl_nr = 1;
|
targets.rl_nr = 1;
|
||||||
|
@ -738,13 +787,13 @@ static IOR_offset_t DAOS_Xfer(int access, void *file, IOR_size_t *buffer,
|
||||||
* written
|
* written
|
||||||
**/
|
**/
|
||||||
total_size += length;
|
total_size += length;
|
||||||
if (param->daosKill && (access == WRITE) &&
|
if (o.daosKill && (access == WRITE) &&
|
||||||
((param->blockSize)/2) == total_size) {
|
((param->blockSize)/2) == total_size) {
|
||||||
/** More than half written lets kill */
|
/** More than half written lets kill */
|
||||||
if (rank == 0)
|
if (rank == 0)
|
||||||
printf("Killing and Syncing\n", rank);
|
printf("Killing and Syncing\n", rank);
|
||||||
kill_and_sync(param);
|
kill_and_sync(param);
|
||||||
param->daosKill = 0;
|
o.daosKill = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -756,17 +805,17 @@ static IOR_offset_t DAOS_Xfer(int access, void *file, IOR_size_t *buffer,
|
||||||
cfs_list_move_tail(&aio->a_list, &aios);
|
cfs_list_move_tail(&aio->a_list, &aios);
|
||||||
nAios--;
|
nAios--;
|
||||||
|
|
||||||
stripe = (param->offset / param->daosStripeSize) %
|
stripe = (param->offset / o.daosStripeSize) %
|
||||||
param->daosStripeCount;
|
o.daosStripeCount;
|
||||||
rc = snprintf(aio->a_dkeyBuf, sizeof aio->a_dkeyBuf, "%lu", stripe);
|
rc = snprintf(aio->a_dkeyBuf, sizeof aio->a_dkeyBuf, "%lu", stripe);
|
||||||
assert(rc < sizeof aio->a_dkeyBuf);
|
assert(rc < sizeof aio->a_dkeyBuf);
|
||||||
aio->a_dkey.iov_len = strlen(aio->a_dkeyBuf) + 1;
|
aio->a_dkey.iov_len = strlen(aio->a_dkeyBuf) + 1;
|
||||||
round = param->offset / (param->daosStripeSize * param->daosStripeCount);
|
round = param->offset / (o.daosStripeSize * o.daosStripeCount);
|
||||||
stripeOffset = param->daosStripeSize * round +
|
stripeOffset = o.daosStripeSize * round +
|
||||||
param->offset % param->daosStripeSize;
|
param->offset % o.daosStripeSize;
|
||||||
if (param->daosStripeMax != 0)
|
if (o.daosStripeMax != 0)
|
||||||
stripeOffset %= param->daosStripeMax;
|
stripeOffset %= o.daosStripeMax;
|
||||||
aio->a_recx.rx_idx = stripeOffset / param->daosRecordSize;
|
aio->a_recx.rx_idx = stripeOffset / o.daosRecordSize;
|
||||||
aio->a_epochRange.epr_lo = fd->epoch;
|
aio->a_epochRange.epr_lo = fd->epoch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -781,7 +830,7 @@ static IOR_offset_t DAOS_Xfer(int access, void *file, IOR_size_t *buffer,
|
||||||
|
|
||||||
INFO(VERBOSE_3, param, "Starting AIO %p (%d free %d busy): access %d "
|
INFO(VERBOSE_3, param, "Starting AIO %p (%d free %d busy): access %d "
|
||||||
"dkey '%s' iod <%llu, %llu> sgl <%p, %lu>", aio, nAios,
|
"dkey '%s' iod <%llu, %llu> sgl <%p, %lu>", aio, nAios,
|
||||||
param->daosAios - nAios, access, (char *) aio->a_dkey.iov_buf,
|
o.daosAios - nAios, access, (char *) aio->a_dkey.iov_buf,
|
||||||
(unsigned long long) aio->a_iod.iod_recxs->rx_idx,
|
(unsigned long long) aio->a_iod.iod_recxs->rx_idx,
|
||||||
(unsigned long long) aio->a_iod.iod_recxs->rx_nr,
|
(unsigned long long) aio->a_iod.iod_recxs->rx_nr,
|
||||||
aio->a_sgl.sg_iovs->iov_buf,
|
aio->a_sgl.sg_iovs->iov_buf,
|
||||||
|
@ -805,7 +854,7 @@ static IOR_offset_t DAOS_Xfer(int access, void *file, IOR_size_t *buffer,
|
||||||
* don't have to return valid data as WriteOrRead() doesn't care.
|
* don't have to return valid data as WriteOrRead() doesn't care.
|
||||||
*/
|
*/
|
||||||
if (access == WRITECHECK || access == READCHECK) {
|
if (access == WRITECHECK || access == READCHECK) {
|
||||||
while (param->daosAios - nAios > 0)
|
while (o.daosAios - nAios > 0)
|
||||||
AIOWait(param);
|
AIOWait(param);
|
||||||
memcpy(buffer, aio->a_sgl.sg_iovs->iov_buf, length);
|
memcpy(buffer, aio->a_sgl.sg_iovs->iov_buf, length);
|
||||||
}
|
}
|
||||||
|
@ -818,13 +867,13 @@ static void DAOS_Close(void *file, IOR_param_t *param)
|
||||||
struct fileDescriptor *fd = file;
|
struct fileDescriptor *fd = file;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
while (param->daosAios - nAios > 0)
|
while (o.daosAios - nAios > 0)
|
||||||
AIOWait(param);
|
AIOWait(param);
|
||||||
AIOFini(param);
|
AIOFini(param);
|
||||||
|
|
||||||
ObjectClose(fd->object);
|
ObjectClose(fd->object);
|
||||||
|
|
||||||
if (param->open == WRITE && !param->daosWriteOnly) {
|
if (param->open == WRITE && !o.daosWriteOnly) {
|
||||||
/* Wait for everybody for to complete the writes. */
|
/* Wait for everybody for to complete the writes. */
|
||||||
MPI_CHECK(MPI_Barrier(param->testComm),
|
MPI_CHECK(MPI_Barrier(param->testComm),
|
||||||
"Failed to synchronize processes");
|
"Failed to synchronize processes");
|
||||||
|
@ -875,7 +924,7 @@ static char* DAOS_GetVersion()
|
||||||
|
|
||||||
static void DAOS_Fsync(void *file, IOR_param_t *param)
|
static void DAOS_Fsync(void *file, IOR_param_t *param)
|
||||||
{
|
{
|
||||||
while (param->daosAios - nAios > 0)
|
while (o.daosAios - nAios > 0)
|
||||||
AIOWait(param);
|
AIOWait(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,672 @@
|
||||||
|
/* -*- 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. *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* GOVERNMENT LICENSE RIGHTS-OPEN SOURCE SOFTWARE
|
||||||
|
* The Government's rights to use, modify, reproduce, release, perform, display,
|
||||||
|
* or disclose this software are subject to the terms of the Apache License as
|
||||||
|
* provided in Contract No. 8F-30005.
|
||||||
|
* Any reproduction of computer software, computer software documentation, or
|
||||||
|
* portions thereof marked with this legend must also reproduce the markings.
|
||||||
|
********************************************************************************
|
||||||
|
*
|
||||||
|
* Implement of abstract I/O interface for DFS.
|
||||||
|
*
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
#include <daos_types.h>
|
||||||
|
#include <daos_api.h>
|
||||||
|
#include <daos_fs.h>
|
||||||
|
|
||||||
|
#include "ior.h"
|
||||||
|
#include "aiori.h"
|
||||||
|
#include "iordef.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
dfs_t *dfs;
|
||||||
|
daos_handle_t poh, coh;
|
||||||
|
|
||||||
|
/************************** O P T I O N S *****************************/
|
||||||
|
struct dfs_options{
|
||||||
|
char * pool;
|
||||||
|
char * svcl;
|
||||||
|
char * group;
|
||||||
|
char * cont;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dfs_options o = {
|
||||||
|
.pool = NULL,
|
||||||
|
.svcl = NULL,
|
||||||
|
.group = NULL,
|
||||||
|
.cont = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static option_help options [] = {
|
||||||
|
{'p', "pool", "DAOS pool uuid", OPTION_REQUIRED_ARGUMENT, 's', & o.pool},
|
||||||
|
{'s', "svcl", "DAOS pool SVCL", OPTION_REQUIRED_ARGUMENT, 's', & o.svcl},
|
||||||
|
{'g', "group", "DAOS server group", OPTION_OPTIONAL_ARGUMENT, 's', & o.group},
|
||||||
|
{'c', "cont", "DFS container uuid", OPTION_REQUIRED_ARGUMENT, 's', & o.cont},
|
||||||
|
LAST_OPTION
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************** P R O T O T Y P E S *****************************/
|
||||||
|
static void *DFS_Create(char *, IOR_param_t *);
|
||||||
|
static void *DFS_Open(char *, IOR_param_t *);
|
||||||
|
static IOR_offset_t DFS_Xfer(int, void *, IOR_size_t *,
|
||||||
|
IOR_offset_t, IOR_param_t *);
|
||||||
|
static void DFS_Close(void *, IOR_param_t *);
|
||||||
|
static void DFS_Delete(char *, IOR_param_t *);
|
||||||
|
static char* DFS_GetVersion();
|
||||||
|
static void DFS_Fsync(void *, IOR_param_t *);
|
||||||
|
static IOR_offset_t DFS_GetFileSize(IOR_param_t *, MPI_Comm, char *);
|
||||||
|
static int DFS_Statfs (const char *, ior_aiori_statfs_t *, IOR_param_t *);
|
||||||
|
static int DFS_Stat (const char *, struct stat *, IOR_param_t *);
|
||||||
|
static int DFS_Mkdir (const char *, mode_t, IOR_param_t *);
|
||||||
|
static int DFS_Rmdir (const char *, IOR_param_t *);
|
||||||
|
static int DFS_Access (const char *, int, IOR_param_t *);
|
||||||
|
static void DFS_Init(IOR_param_t *param);
|
||||||
|
static void DFS_Finalize(IOR_param_t *param);
|
||||||
|
static option_help * DFS_options();
|
||||||
|
|
||||||
|
/************************** D E C L A R A T I O N S ***************************/
|
||||||
|
|
||||||
|
ior_aiori_t dfs_aiori = {
|
||||||
|
.name = "DFS",
|
||||||
|
.create = DFS_Create,
|
||||||
|
.open = DFS_Open,
|
||||||
|
.xfer = DFS_Xfer,
|
||||||
|
.close = DFS_Close,
|
||||||
|
.delete = DFS_Delete,
|
||||||
|
.get_version = DFS_GetVersion,
|
||||||
|
.fsync = DFS_Fsync,
|
||||||
|
.get_file_size = DFS_GetFileSize,
|
||||||
|
.statfs = DFS_Statfs,
|
||||||
|
.mkdir = DFS_Mkdir,
|
||||||
|
.rmdir = DFS_Rmdir,
|
||||||
|
.access = DFS_Access,
|
||||||
|
.stat = DFS_Stat,
|
||||||
|
.initialize = DFS_Init,
|
||||||
|
.finalize = DFS_Finalize,
|
||||||
|
.get_options = DFS_options,
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************** 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, "ERROR (%s:%d): %d: %d: " \
|
||||||
|
format"\n", __FILE__, __LINE__, rank, _rc, \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
fflush(stderr); \
|
||||||
|
MPI_Abort(MPI_COMM_WORLD, -1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DERR(rc, format, ...) \
|
||||||
|
do { \
|
||||||
|
int _rc = (rc); \
|
||||||
|
\
|
||||||
|
if (_rc < 0) { \
|
||||||
|
fprintf(stderr, "ERROR (%s:%d): %d: %d: " \
|
||||||
|
format"\n", __FILE__, __LINE__, rank, _rc, \
|
||||||
|
##__VA_ARGS__); \
|
||||||
|
fflush(stderr); \
|
||||||
|
goto out; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_filename(const char *path, char **_obj_name, char **_cont_name)
|
||||||
|
{
|
||||||
|
char *f1 = NULL;
|
||||||
|
char *f2 = NULL;
|
||||||
|
char *fname = NULL;
|
||||||
|
char *cont_name = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (path == NULL || _obj_name == NULL || _cont_name == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (strcmp(path, "/") == 0) {
|
||||||
|
*_cont_name = strdup("/");
|
||||||
|
if (*_cont_name == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
*_obj_name = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f1 = strdup(path);
|
||||||
|
if (f1 == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
|
||||||
|
f2 = strdup(path);
|
||||||
|
if (f2 == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
|
||||||
|
fname = basename(f1);
|
||||||
|
cont_name = dirname(f2);
|
||||||
|
|
||||||
|
if (cont_name[0] == '.' || cont_name[0] != '/') {
|
||||||
|
char cwd[1024];
|
||||||
|
|
||||||
|
if (getcwd(cwd, 1024) == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
|
||||||
|
if (strcmp(cont_name, ".") == 0) {
|
||||||
|
cont_name = strdup(cwd);
|
||||||
|
if (cont_name == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
} else {
|
||||||
|
char *new_dir = calloc(strlen(cwd) + strlen(cont_name)
|
||||||
|
+ 1, sizeof(char));
|
||||||
|
if (new_dir == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
|
||||||
|
strcpy(new_dir, cwd);
|
||||||
|
if (cont_name[0] == '.') {
|
||||||
|
strcat(new_dir, &cont_name[1]);
|
||||||
|
} else {
|
||||||
|
strcat(new_dir, "/");
|
||||||
|
strcat(new_dir, cont_name);
|
||||||
|
}
|
||||||
|
cont_name = new_dir;
|
||||||
|
}
|
||||||
|
*_cont_name = cont_name;
|
||||||
|
} else {
|
||||||
|
*_cont_name = strdup(cont_name);
|
||||||
|
if (*_cont_name == NULL)
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
*_obj_name = strdup(fname);
|
||||||
|
if (*_obj_name == NULL) {
|
||||||
|
free(*_cont_name);
|
||||||
|
*_cont_name = NULL;
|
||||||
|
D_GOTO(out, rc = -ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (f1)
|
||||||
|
free(f1);
|
||||||
|
if (f2)
|
||||||
|
free(f2);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static option_help * DFS_options(){
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DFS_Init(IOR_param_t *param) {
|
||||||
|
uuid_t pool_uuid, co_uuid;
|
||||||
|
daos_pool_info_t pool_info;
|
||||||
|
daos_cont_info_t co_info;
|
||||||
|
d_rank_list_t *svcl = NULL;
|
||||||
|
bool cont_created = false;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (o.pool == NULL || o.svcl == NULL || o.cont == NULL)
|
||||||
|
ERR("Invalid Arguments to DFS\n");
|
||||||
|
|
||||||
|
rc = uuid_parse(o.pool, pool_uuid);
|
||||||
|
DCHECK(rc, "Failed to parse 'Pool uuid': %s", o.pool);
|
||||||
|
|
||||||
|
rc = uuid_parse(o.cont, co_uuid);
|
||||||
|
DCHECK(rc, "Failed to parse 'Cont uuid': %s", o.cont);
|
||||||
|
|
||||||
|
svcl = daos_rank_list_parse(o.svcl, ":");
|
||||||
|
if (svcl == NULL)
|
||||||
|
ERR("Failed to allocate svcl");
|
||||||
|
|
||||||
|
if (verbose >= 3) {
|
||||||
|
printf("Pool uuid = %s, SVCL = %s\n", o.pool, o.svcl);
|
||||||
|
printf("DFS Container namespace uuid = %s\n", o.cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = daos_init();
|
||||||
|
DCHECK(rc, "Failed to initialize daos");
|
||||||
|
|
||||||
|
/** Connect to DAOS pool */
|
||||||
|
rc = daos_pool_connect(pool_uuid, o.group, svcl, DAOS_PC_RW, &poh,
|
||||||
|
&pool_info, NULL);
|
||||||
|
DCHECK(rc, "Failed to connect to pool");
|
||||||
|
|
||||||
|
rc = daos_cont_open(poh, co_uuid, DAOS_COO_RW, &coh, &co_info, NULL);
|
||||||
|
/* If NOEXIST we create it */
|
||||||
|
if (rc == -DER_NONEXIST) {
|
||||||
|
if (verbose >= 3)
|
||||||
|
printf("Creating DFS Container ...\n");
|
||||||
|
rc = daos_cont_create(poh, co_uuid, NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
cont_created = true;
|
||||||
|
rc = daos_cont_open(poh, co_uuid, DAOS_COO_RW, &coh,
|
||||||
|
&co_info, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCHECK(rc, "Failed to create container");
|
||||||
|
|
||||||
|
rc = dfs_mount(poh, coh, O_RDWR, &dfs);
|
||||||
|
DCHECK(rc, "Failed to mount DFS namespace");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DFS_Finalize(IOR_param_t *param)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = dfs_umount(dfs, true);
|
||||||
|
DCHECK(rc, "Failed to umount DFS namespace");
|
||||||
|
|
||||||
|
rc = daos_cont_close(coh, NULL);
|
||||||
|
DCHECK(rc, "Failed to close container");
|
||||||
|
|
||||||
|
daos_pool_disconnect(poh, NULL);
|
||||||
|
DCHECK(rc, "Failed to disconnect from pool");
|
||||||
|
|
||||||
|
rc = daos_fini();
|
||||||
|
DCHECK(rc, "Failed to finalize DAOS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creat and open a file through the DFS interface.
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
DFS_Create(char *testFileName, IOR_param_t *param)
|
||||||
|
{
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
dfs_obj_t *obj = NULL, *parent = NULL;
|
||||||
|
mode_t pmode, mode;
|
||||||
|
int fd_oflag = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
assert(param);
|
||||||
|
|
||||||
|
fd_oflag |= O_CREAT | O_RDWR;
|
||||||
|
mode = S_IFREG | param->mode;
|
||||||
|
|
||||||
|
rc = parse_filename(testFileName, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", testFileName);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_open(dfs, parent, name, mode, fd_oflag, DAOS_OC_LARGE_RW,
|
||||||
|
NULL, &obj);
|
||||||
|
DERR(rc, "dfs_open() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
|
||||||
|
return ((void *)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a file through the DFS interface.
|
||||||
|
*/
|
||||||
|
static void *
|
||||||
|
DFS_Open(char *testFileName, IOR_param_t *param)
|
||||||
|
{
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
dfs_obj_t *obj = NULL, *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
int rc;
|
||||||
|
int fd_oflag = 0;
|
||||||
|
|
||||||
|
fd_oflag |= O_RDWR;
|
||||||
|
|
||||||
|
rc = parse_filename(testFileName, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", testFileName);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_open(dfs, parent, name, S_IFREG, fd_oflag, 0, NULL, &obj);
|
||||||
|
DERR(rc, "dfs_open() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
|
||||||
|
return ((void *)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write or read access to file using the DFS interface.
|
||||||
|
*/
|
||||||
|
static IOR_offset_t
|
||||||
|
DFS_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;
|
||||||
|
daos_size_t ret;
|
||||||
|
int rc;
|
||||||
|
dfs_obj_t *obj;
|
||||||
|
|
||||||
|
obj = (dfs_obj_t *)file;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
daos_iov_t iov;
|
||||||
|
daos_sg_list_t sgl;
|
||||||
|
|
||||||
|
/** set memory location */
|
||||||
|
sgl.sg_nr = 1;
|
||||||
|
sgl.sg_nr_out = 0;
|
||||||
|
daos_iov_set(&iov, (void *)ptr, remaining);
|
||||||
|
sgl.sg_iovs = &iov;
|
||||||
|
|
||||||
|
/* write/read file */
|
||||||
|
if (access == WRITE) {
|
||||||
|
rc = dfs_write(dfs, obj, sgl, param->offset);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "dfs_write() failed (%d)", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = remaining;
|
||||||
|
} else {
|
||||||
|
rc = dfs_read(dfs, obj, sgl, param->offset, &ret);
|
||||||
|
if (rc || ret == 0)
|
||||||
|
fprintf(stderr, "dfs_read() failed(%d)", rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 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(ret >= 0);
|
||||||
|
assert(ret <= remaining);
|
||||||
|
remaining -= ret;
|
||||||
|
ptr += ret;
|
||||||
|
xferRetries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform fsync().
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DFS_Fsync(void *fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_sync(dfs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close a file through the DFS interface.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DFS_Close(void *fd, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_release((dfs_obj_t *)fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete a file through the DFS interface.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DFS_Delete(char *testFileName, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
dfs_obj_t *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_filename(testFileName, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", testFileName);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_remove(dfs, parent, name, false);
|
||||||
|
DERR(rc, "dfs_remove() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* DFS_GetVersion()
|
||||||
|
{
|
||||||
|
static char ver[1024] = {};
|
||||||
|
|
||||||
|
sprintf(ver, "%s", "DAOS");
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use DFS stat() to return aggregate file size.
|
||||||
|
*/
|
||||||
|
static IOR_offset_t
|
||||||
|
DFS_GetFileSize(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
|
||||||
|
{
|
||||||
|
dfs_obj_t *obj;
|
||||||
|
daos_size_t fsize, tmpMin, tmpMax, tmpSum;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, testFileName, O_RDONLY, &obj, NULL);
|
||||||
|
if (rc) {
|
||||||
|
fprintf(stderr, "dfs_lookup() of %s Failed (%d)", testFileName, rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = dfs_get_size(dfs, obj, &fsize);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
dfs_release(obj);
|
||||||
|
|
||||||
|
if (test->filePerProc == TRUE) {
|
||||||
|
MPI_CHECK(MPI_Allreduce(&fsize, &tmpSum, 1,
|
||||||
|
MPI_LONG_LONG_INT, MPI_SUM, testComm),
|
||||||
|
"cannot total data moved");
|
||||||
|
fsize = tmpSum;
|
||||||
|
} else {
|
||||||
|
MPI_CHECK(MPI_Allreduce(&fsize, &tmpMin, 1,
|
||||||
|
MPI_LONG_LONG_INT, MPI_MIN, testComm),
|
||||||
|
"cannot total data moved");
|
||||||
|
MPI_CHECK(MPI_Allreduce(&fsize, &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 */
|
||||||
|
fsize = tmpMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DFS_Statfs(const char *path, ior_aiori_statfs_t *sfs, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DFS_Mkdir(const char *path, mode_t mode, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_obj_t *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_filename(path, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", path);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_mkdir(dfs, parent, name, mode);
|
||||||
|
DERR(rc, "dfs_mkdir() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DFS_Rmdir(const char *path, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_obj_t *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_filename(path, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", path);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_remove(dfs, parent, name, false);
|
||||||
|
DERR(rc, "dfs_remove() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DFS_Access(const char *path, int mode, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_obj_t *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
struct stat stbuf;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_filename(path, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", path);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDWR, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
if (name && strcmp(name, ".") == 0) {
|
||||||
|
free(name);
|
||||||
|
name = NULL;
|
||||||
|
}
|
||||||
|
rc = dfs_stat(dfs, parent, name, &stbuf);
|
||||||
|
DERR(rc, "dfs_stat() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DFS_Stat(const char *path, struct stat *buf, IOR_param_t * param)
|
||||||
|
{
|
||||||
|
dfs_obj_t *parent = NULL;
|
||||||
|
mode_t pmode;
|
||||||
|
char *name = NULL, *dir_name = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = parse_filename(path, &name, &dir_name);
|
||||||
|
DERR(rc, "Failed to parse path %s", path);
|
||||||
|
|
||||||
|
assert(dir_name);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
rc = dfs_lookup(dfs, dir_name, O_RDONLY, &parent, &pmode);
|
||||||
|
DERR(rc, "dfs_lookup() of %s Failed", dir_name);
|
||||||
|
|
||||||
|
rc = dfs_stat(dfs, parent, name, buf);
|
||||||
|
DERR(rc, "dfs_stat() of %s Failed", name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (dir_name)
|
||||||
|
free(dir_name);
|
||||||
|
if (parent)
|
||||||
|
dfs_release(parent);
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
return rc;
|
||||||
|
}
|
|
@ -60,6 +60,7 @@ ior_aiori_t *available_aiori[] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_DAOS_AIORI
|
#ifdef USE_DAOS_AIORI
|
||||||
&daos_aiori,
|
&daos_aiori,
|
||||||
|
&dfs_aiori,
|
||||||
#endif
|
#endif
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -97,6 +97,7 @@ extern ior_aiori_t s3_plus_aiori;
|
||||||
extern ior_aiori_t s3_emc_aiori;
|
extern ior_aiori_t s3_emc_aiori;
|
||||||
extern ior_aiori_t rados_aiori;
|
extern ior_aiori_t rados_aiori;
|
||||||
extern ior_aiori_t daos_aiori;
|
extern ior_aiori_t daos_aiori;
|
||||||
|
extern ior_aiori_t dfs_aiori;
|
||||||
|
|
||||||
void aiori_initialize(IOR_test_t *th);
|
void aiori_initialize(IOR_test_t *th);
|
||||||
void aiori_finalize(IOR_test_t *th);
|
void aiori_finalize(IOR_test_t *th);
|
||||||
|
|
|
@ -315,7 +315,8 @@ void ShowTestStart(IOR_param_t *test)
|
||||||
PrintKeyValInt("TestID", test->id);
|
PrintKeyValInt("TestID", test->id);
|
||||||
PrintKeyVal("StartTime", CurrentTimeString());
|
PrintKeyVal("StartTime", CurrentTimeString());
|
||||||
/* if pvfs2:, then skip */
|
/* if pvfs2:, then skip */
|
||||||
if (Regex(test->testFileName, "^[a-z][a-z].*:") == 0) {
|
if (strcasecmp(test->api, "DFS") &&
|
||||||
|
Regex(test->testFileName, "^[a-z][a-z].*:") == 0) {
|
||||||
DisplayFreespace(test);
|
DisplayFreespace(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/ior.c
15
src/ior.c
|
@ -123,8 +123,6 @@ int ior_main(int argc, char **argv)
|
||||||
|
|
||||||
PrintHeader(argc, argv);
|
PrintHeader(argc, argv);
|
||||||
|
|
||||||
aiori_initialize(tests_head);
|
|
||||||
|
|
||||||
/* perform each test */
|
/* perform each test */
|
||||||
for (tptr = tests_head; tptr != NULL; tptr = tptr->next) {
|
for (tptr = tests_head; tptr != NULL; tptr = tptr->next) {
|
||||||
verbose = tptr->params.verbose;
|
verbose = tptr->params.verbose;
|
||||||
|
@ -139,12 +137,11 @@ int ior_main(int argc, char **argv)
|
||||||
sleep(5);
|
sleep(5);
|
||||||
fprintf(out_logfile, "\trank %d: awake.\n", rank);
|
fprintf(out_logfile, "\trank %d: awake.\n", rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestIoSys(tptr);
|
TestIoSys(tptr);
|
||||||
ShowTestEnd(tptr);
|
ShowTestEnd(tptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiori_finalize(tests_head);
|
|
||||||
|
|
||||||
if (verbose < 0)
|
if (verbose < 0)
|
||||||
/* always print final summary */
|
/* always print final summary */
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
|
@ -199,11 +196,6 @@ void init_IOR_Param_t(IOR_param_t * p)
|
||||||
p->setAlignment = 1;
|
p->setAlignment = 1;
|
||||||
p->lustre_start_ost = -1;
|
p->lustre_start_ost = -1;
|
||||||
|
|
||||||
p->daosRecordSize = 262144;
|
|
||||||
p->daosStripeSize = 524288;
|
|
||||||
p->daosStripeCount = -1;
|
|
||||||
p->daosAios = 1;
|
|
||||||
|
|
||||||
hdfs_user = getenv("USER");
|
hdfs_user = getenv("USER");
|
||||||
if (!hdfs_user)
|
if (!hdfs_user)
|
||||||
hdfs_user = "";
|
hdfs_user = "";
|
||||||
|
@ -1194,6 +1186,9 @@ static void TestIoSys(IOR_test_t *test)
|
||||||
/* bind I/O calls to specific API */
|
/* bind I/O calls to specific API */
|
||||||
backend = aiori_select(params->api);
|
backend = aiori_select(params->api);
|
||||||
|
|
||||||
|
if (backend->initialize)
|
||||||
|
backend->initialize(params);
|
||||||
|
|
||||||
/* show test setup */
|
/* show test setup */
|
||||||
if (rank == 0 && verbose >= VERBOSE_0)
|
if (rank == 0 && verbose >= VERBOSE_0)
|
||||||
ShowSetup(params);
|
ShowSetup(params);
|
||||||
|
@ -1478,6 +1473,8 @@ static void TestIoSys(IOR_test_t *test)
|
||||||
free(timer[i]);
|
free(timer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backend->finalize)
|
||||||
|
backend->finalize(NULL);
|
||||||
/* Sync with the tasks that did not participate in this test */
|
/* Sync with the tasks that did not participate in this test */
|
||||||
MPI_CHECK(MPI_Barrier(mpi_comm_world), "barrier error");
|
MPI_CHECK(MPI_Barrier(mpi_comm_world), "barrier error");
|
||||||
|
|
||||||
|
|
15
src/ior.h
15
src/ior.h
|
@ -190,21 +190,6 @@ typedef struct
|
||||||
int lustre_set_striping; /* flag that we need to set lustre striping */
|
int lustre_set_striping; /* flag that we need to set lustre striping */
|
||||||
int lustre_ignore_locks;
|
int lustre_ignore_locks;
|
||||||
|
|
||||||
/* DAOS variables */
|
|
||||||
char daosGroup[MAX_STR]; /* group name */
|
|
||||||
char daosPool[37]; /* pool UUID */
|
|
||||||
char daosPoolSvc[MAX_STR]; /* pool service ranks */
|
|
||||||
int daosRecordSize; /* size of akey record (i.e., rx_rsize) */
|
|
||||||
int daosStripeSize;
|
|
||||||
unsigned long daosStripeCount;
|
|
||||||
unsigned long daosStripeMax; /* max length of a stripe */
|
|
||||||
int daosAios; /* max number of concurrent async I/Os */
|
|
||||||
int daosWriteOnly; /* write only, no flush and commit */
|
|
||||||
unsigned long daosEpoch; /* epoch to access */
|
|
||||||
unsigned long daosWait; /* epoch to wait for before reading */
|
|
||||||
int daosKill; /* kill a target while running IOR */
|
|
||||||
char daosObjectClass[MAX_STR]; /* object class */
|
|
||||||
|
|
||||||
/* gpfs variables */
|
/* gpfs variables */
|
||||||
int gpfs_hint_access; /* use gpfs "access range" hint */
|
int gpfs_hint_access; /* use gpfs "access range" hint */
|
||||||
int gpfs_release_token; /* immediately release GPFS tokens after
|
int gpfs_release_token; /* immediately release GPFS tokens after
|
||||||
|
|
|
@ -3,11 +3,9 @@
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
MPI_Init(&argc, &argv);
|
MPI_Init(&argc, &argv);
|
||||||
aiori_initialize(NULL);
|
|
||||||
|
|
||||||
mdtest_run(argc, argv, MPI_COMM_WORLD, stdout);
|
mdtest_run(argc, argv, MPI_COMM_WORLD, stdout);
|
||||||
|
|
||||||
aiori_finalize(NULL);
|
|
||||||
MPI_Finalize();
|
MPI_Finalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
15
src/mdtest.c
15
src/mdtest.c
|
@ -1615,8 +1615,9 @@ void valid_tests() {
|
||||||
FAIL("-c not compatible with -B");
|
FAIL("-c not compatible with -B");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strcasecmp(backend_name, "POSIX") != 0 && strcasecmp(backend_name, "DUMMY") != 0) {
|
if ( strcasecmp(backend_name, "POSIX") != 0 && strcasecmp(backend_name, "DUMMY") != 0 &&
|
||||||
FAIL("-a only supported interface is POSIX (and DUMMY) right now!");
|
strcasecmp(backend_name, "DFS") != 0) {
|
||||||
|
FAIL("-a only supported interface is POSIX, DFS and DUMMY right now!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for shared file incompatibilities */
|
/* check for shared file incompatibilities */
|
||||||
|
@ -1757,6 +1758,9 @@ void display_freespace(char *testdirpath)
|
||||||
strcpy(dirpath, ".");
|
strcpy(dirpath, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(backend_name, "DFS") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (verbose >= 3 && rank == 0) {
|
if (verbose >= 3 && rank == 0) {
|
||||||
fprintf(out_logfile, "V-3: Before show_file_system_size, dirpath is \"%s\"\n", dirpath );
|
fprintf(out_logfile, "V-3: Before show_file_system_size, dirpath is \"%s\"\n", dirpath );
|
||||||
fflush( out_logfile );
|
fflush( out_logfile );
|
||||||
|
@ -2223,6 +2227,9 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
|
||||||
option_parse(argc - parsed_options, argv + parsed_options, backend->get_options(), & printhelp);
|
option_parse(argc - parsed_options, argv + parsed_options, backend->get_options(), & printhelp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backend->initialize)
|
||||||
|
backend->initialize(NULL);
|
||||||
|
|
||||||
if(printhelp != 0){
|
if(printhelp != 0){
|
||||||
printf("Usage: %s ", argv[0]);
|
printf("Usage: %s ", argv[0]);
|
||||||
|
|
||||||
|
@ -2517,5 +2524,9 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
|
||||||
if (random_seed > 0) {
|
if (random_seed > 0) {
|
||||||
free(rand_array);
|
free(rand_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backend->finalize)
|
||||||
|
backend->finalize(NULL);
|
||||||
|
|
||||||
return summary_table;
|
return summary_table;
|
||||||
}
|
}
|
||||||
|
|
12
src/option.c
12
src/option.c
|
@ -89,6 +89,10 @@ static int print_value(option_help * o){
|
||||||
pos += printf("=%lld", *(long long*) o->variable);
|
pos += printf("=%lld", *(long long*) o->variable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case('u'):{
|
||||||
|
pos += printf("=%lu", *(uint64_t*) o->variable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (o->arg == OPTION_FLAG && (*(int*)o->variable) != 0){
|
if (o->arg == OPTION_FLAG && (*(int*)o->variable) != 0){
|
||||||
|
@ -213,6 +217,10 @@ static int print_option_value(option_help * o){
|
||||||
pos += printf("=%lld", *(long long*) o->variable);
|
pos += printf("=%lld", *(long long*) o->variable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case('u'):{
|
||||||
|
pos += printf("=%lu", *(uint64_t*) o->variable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
//printf(" ");
|
//printf(" ");
|
||||||
|
@ -354,6 +362,10 @@ int option_parse(int argc, char ** argv, option_help * args, int * printhelp){
|
||||||
*(long long*) o->variable = string_to_bytes(arg);
|
*(long long*) o->variable = string_to_bytes(arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case('u'):{
|
||||||
|
*(uint64_t*) o->variable = string_to_bytes(arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
printf("ERROR: Unknown option type %c\n", o->type);
|
printf("ERROR: Unknown option type %c\n", o->type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,32 +300,6 @@ void DecodeDirective(char *line, IOR_param_t *params)
|
||||||
params->numTasks = atoi(value);
|
params->numTasks = atoi(value);
|
||||||
} else if (strcasecmp(option, "summaryalways") == 0) {
|
} else if (strcasecmp(option, "summaryalways") == 0) {
|
||||||
params->summary_every_test = atoi(value);
|
params->summary_every_test = atoi(value);
|
||||||
} else if (strcasecmp(option, "daosgroup") == 0) {
|
|
||||||
strcpy(params->daosGroup, value);
|
|
||||||
} else if (strcasecmp(option, "daospool") == 0) {
|
|
||||||
strcpy(params->daosPool, value);
|
|
||||||
} else if (strcasecmp(option, "daospoolsvc") == 0) {
|
|
||||||
strcpy(params->daosPoolSvc, value);
|
|
||||||
} else if (strcasecmp(option, "daosrecordsize") == 0) {
|
|
||||||
params->daosRecordSize = string_to_bytes(value);
|
|
||||||
} else if (strcasecmp(option, "daosstripesize") == 0) {
|
|
||||||
params->daosStripeSize = string_to_bytes(value);
|
|
||||||
} else if (strcasecmp(option, "daosstripecount") == 0) {
|
|
||||||
params->daosStripeCount = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daosstripemax") == 0) {
|
|
||||||
params->daosStripeMax = string_to_bytes(value);
|
|
||||||
} else if (strcasecmp(option, "daosaios") == 0) {
|
|
||||||
params->daosAios = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daosepoch") == 0) {
|
|
||||||
params->daosEpoch = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daoswait") == 0) {
|
|
||||||
params->daosWait = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daoswriteonly") == 0) {
|
|
||||||
params->daosWriteOnly = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daoskill") == 0) {
|
|
||||||
params->daosKill = atoi(value);
|
|
||||||
} else if (strcasecmp(option, "daosobjectclass") == 0) {
|
|
||||||
strcpy(params->daosObjectClass, value);
|
|
||||||
} else {
|
} else {
|
||||||
if (rank == 0)
|
if (rank == 0)
|
||||||
fprintf(out_logfile, "Unrecognized parameter \"%s\"\n",
|
fprintf(out_logfile, "Unrecognized parameter \"%s\"\n",
|
||||||
|
|
Loading…
Reference in New Issue