2012-01-09 00:51:04 +04:00
|
|
|
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
|
|
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
|
|
*/
|
2011-06-17 23:20:43 +04:00
|
|
|
/******************************************************************************\
|
|
|
|
* *
|
|
|
|
* Copyright (c) 2003, The Regents of the University of California *
|
|
|
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
|
|
|
* *
|
|
|
|
********************************************************************************
|
|
|
|
*
|
2011-10-28 01:12:26 +04:00
|
|
|
* Implement of abstract I/O interface for POSIX.
|
2011-06-17 23:20:43 +04:00
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
2011-11-12 04:40:45 +04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2014-09-18 21:20:37 +04:00
|
|
|
# include "config.h"
|
2011-11-12 04:40:45 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2014-09-18 21:20:37 +04:00
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
#ifdef __linux__
|
2014-09-18 21:20:37 +04:00
|
|
|
# include <sys/ioctl.h> /* necessary for: */
|
|
|
|
# define __USE_GNU /* O_DIRECT and */
|
|
|
|
# include <fcntl.h> /* IO operations */
|
|
|
|
# undef __USE_GNU
|
2011-11-12 02:22:17 +04:00
|
|
|
#endif /* __linux__ */
|
2014-09-18 21:20:37 +04:00
|
|
|
|
2011-11-12 04:40:45 +04:00
|
|
|
#include <errno.h>
|
2011-11-12 02:22:17 +04:00
|
|
|
#include <fcntl.h> /* IO operations */
|
2011-06-17 23:20:43 +04:00
|
|
|
#include <sys/stat.h>
|
2011-11-11 07:01:34 +04:00
|
|
|
#include <assert.h>
|
2014-09-18 21:20:37 +04:00
|
|
|
|
2018-08-29 00:27:21 +03:00
|
|
|
|
|
|
|
#ifdef HAVE_LINUX_LUSTRE_LUSTRE_USER_H
|
|
|
|
# include <linux/lustre/lustre_user.h>
|
2020-06-24 12:15:31 +03:00
|
|
|
#elif defined(HAVE_LUSTRE_USER)
|
2018-12-15 02:26:16 +03:00
|
|
|
# include <lustre/lustre_user.h>
|
2018-08-29 00:27:21 +03:00
|
|
|
#endif
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_H
|
2014-09-18 21:20:37 +04:00
|
|
|
# include <gpfs.h>
|
2013-09-26 17:48:50 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
2014-09-18 21:20:37 +04:00
|
|
|
# include <gpfs_fcntl.h>
|
2013-09-26 17:48:50 +04:00
|
|
|
#endif
|
|
|
|
|
2017-09-21 18:12:31 +03:00
|
|
|
#ifdef HAVE_BEEGFS_BEEGFS_H
|
|
|
|
#include <beegfs/beegfs.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <libgen.h>
|
|
|
|
#endif
|
|
|
|
|
2011-11-12 04:40:45 +04:00
|
|
|
#include "ior.h"
|
|
|
|
#include "aiori.h"
|
|
|
|
#include "iordef.h"
|
2014-09-18 21:20:37 +04:00
|
|
|
#include "utilities.h"
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2020-07-21 18:16:13 +03:00
|
|
|
#include "aiori-POSIX.h"
|
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
typedef long long loff_t;
|
|
|
|
#include <cuda_runtime.h>
|
|
|
|
#include <cufile.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int fd;
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
CUfileHandle_t cf_handle;
|
|
|
|
#endif
|
|
|
|
} posix_fd;
|
|
|
|
|
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
#ifndef open64 /* necessary for TRU64 -- */
|
2014-09-18 21:20:37 +04:00
|
|
|
# define open64 open /* unlikely, but may pose */
|
2011-11-12 02:22:17 +04:00
|
|
|
#endif /* not open64 */ /* conflicting prototypes */
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
#ifndef lseek64 /* necessary for TRU64 -- */
|
2014-09-18 21:20:37 +04:00
|
|
|
# define lseek64 lseek /* unlikely, but may pose */
|
2011-11-12 02:22:17 +04:00
|
|
|
#endif /* not lseek64 */ /* conflicting prototypes */
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
#ifndef O_BINARY /* Required on Windows */
|
2014-09-18 21:20:37 +04:00
|
|
|
# define O_BINARY 0
|
2011-06-17 23:20:43 +04:00
|
|
|
#endif
|
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
static const char* cuFileGetErrorString(CUfileError_t status){
|
|
|
|
if(IS_CUDA_ERR(status)){
|
|
|
|
return cudaGetErrorString(status.err);
|
|
|
|
}
|
|
|
|
return strerror(status.err);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void init_cufile(posix_fd * pfd){
|
|
|
|
CUfileDescr_t cf_descr = (CUfileDescr_t){
|
|
|
|
.handle.fd = pfd->fd,
|
|
|
|
.type = CU_FILE_HANDLE_TYPE_OPAQUE_FD
|
|
|
|
};
|
|
|
|
CUfileError_t status = cuFileHandleRegister(& pfd->cf_handle, & cf_descr);
|
|
|
|
if(status.err != CU_FILE_SUCCESS){
|
|
|
|
EWARNF("Could not register handle %s", cuFileGetErrorString(status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/**************************** P R O T O T Y P E S *****************************/
|
2021-02-18 13:40:42 +03:00
|
|
|
static void POSIX_Initialize(aiori_mod_opt_t * options);
|
|
|
|
static void POSIX_Finalize(aiori_mod_opt_t * options);
|
|
|
|
|
2020-05-31 14:11:00 +03:00
|
|
|
static IOR_offset_t POSIX_Xfer(int, aiori_fd_t *, IOR_size_t *,
|
2020-06-10 19:47:07 +03:00
|
|
|
IOR_offset_t, IOR_offset_t, aiori_mod_opt_t *);
|
2019-03-27 23:04:48 +03:00
|
|
|
|
2020-05-31 13:58:34 +03:00
|
|
|
option_help * POSIX_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){
|
2019-03-27 23:04:48 +03:00
|
|
|
posix_options_t * o = malloc(sizeof(posix_options_t));
|
|
|
|
|
|
|
|
if (init_values != NULL){
|
|
|
|
memcpy(o, init_values, sizeof(posix_options_t));
|
|
|
|
}else{
|
2020-05-30 22:09:37 +03:00
|
|
|
memset(o, 0, sizeof(posix_options_t));
|
2019-03-27 23:04:48 +03:00
|
|
|
o->direct_io = 0;
|
2020-11-26 18:56:34 +03:00
|
|
|
o->lustre_stripe_count = -1;
|
2020-05-30 22:09:37 +03:00
|
|
|
o->lustre_start_ost = -1;
|
|
|
|
o->beegfs_numTargets = -1;
|
|
|
|
o->beegfs_chunkSize = -1;
|
2019-03-27 23:04:48 +03:00
|
|
|
}
|
|
|
|
|
2020-05-31 13:58:34 +03:00
|
|
|
*init_backend_options = (aiori_mod_opt_t*) o;
|
2019-03-27 23:04:48 +03:00
|
|
|
|
|
|
|
option_help h [] = {
|
|
|
|
{0, "posix.odirect", "Direct I/O Mode", OPTION_FLAG, 'd', & o->direct_io},
|
2020-05-30 22:09:37 +03:00
|
|
|
#ifdef HAVE_BEEGFS_BEEGFS_H
|
|
|
|
{0, "posix.beegfs.NumTargets", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->beegfs_numTargets},
|
|
|
|
{0, "posix.beegfs.ChunkSize", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->beegfs_chunkSize},
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
|
|
|
{0, "posix.gpfs.hintaccess", "", OPTION_FLAG, 'd', & o->gpfs_hint_access},
|
|
|
|
{0, "posix.gpfs.releasetoken", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->gpfs_release_token},
|
|
|
|
|
|
|
|
#endif
|
2020-06-24 12:15:31 +03:00
|
|
|
#ifdef HAVE_LUSTRE_USER
|
2020-11-04 22:27:39 +03:00
|
|
|
{0, "posix.lustre.stripecount", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->lustre_stripe_count},
|
2020-05-30 22:09:37 +03:00
|
|
|
{0, "posix.lustre.stripesize", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->lustre_stripe_size},
|
|
|
|
{0, "posix.lustre.startost", "", OPTION_OPTIONAL_ARGUMENT, 'd', & o->lustre_start_ost},
|
|
|
|
{0, "posix.lustre.ignorelocks", "", OPTION_FLAG, 'd', & o->lustre_ignore_locks},
|
2021-02-18 13:40:42 +03:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
{0, "gpuDirect", "allocate I/O buffers on the GPU", OPTION_FLAG, 'd', & o->gpuDirect},
|
2020-05-30 22:09:37 +03:00
|
|
|
#endif
|
2019-03-27 23:04:48 +03:00
|
|
|
LAST_OPTION
|
|
|
|
};
|
|
|
|
option_help * help = malloc(sizeof(h));
|
|
|
|
memcpy(help, h, sizeof(h));
|
|
|
|
return help;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/************************** D E C L A R A T I O N S ***************************/
|
|
|
|
|
2019-03-27 23:04:48 +03:00
|
|
|
|
2011-10-28 03:50:05 +04:00
|
|
|
ior_aiori_t posix_aiori = {
|
2017-10-20 00:26:52 +03:00
|
|
|
.name = "POSIX",
|
2018-09-10 19:43:12 +03:00
|
|
|
.name_legacy = NULL,
|
2021-02-18 13:40:42 +03:00
|
|
|
.initialize = POSIX_Initialize,
|
|
|
|
.finalize = POSIX_Finalize,
|
2017-10-20 00:26:52 +03:00
|
|
|
.create = POSIX_Create,
|
2018-10-08 15:30:47 +03:00
|
|
|
.mknod = POSIX_Mknod,
|
2017-10-20 00:26:52 +03:00
|
|
|
.open = POSIX_Open,
|
|
|
|
.xfer = POSIX_Xfer,
|
|
|
|
.close = POSIX_Close,
|
|
|
|
.delete = POSIX_Delete,
|
2020-07-21 18:16:13 +03:00
|
|
|
.xfer_hints = POSIX_xfer_hints,
|
2018-07-14 10:41:35 +03:00
|
|
|
.get_version = aiori_get_version,
|
2017-10-20 00:26:52 +03:00
|
|
|
.fsync = POSIX_Fsync,
|
|
|
|
.get_file_size = POSIX_GetFileSize,
|
2018-04-26 01:34:25 +03:00
|
|
|
.statfs = aiori_posix_statfs,
|
|
|
|
.mkdir = aiori_posix_mkdir,
|
|
|
|
.rmdir = aiori_posix_rmdir,
|
2021-01-21 17:10:23 +03:00
|
|
|
.rename = POSIX_Rename,
|
2018-04-26 01:34:25 +03:00
|
|
|
.access = aiori_posix_access,
|
|
|
|
.stat = aiori_posix_stat,
|
2019-03-28 01:32:59 +03:00
|
|
|
.get_options = POSIX_options,
|
2019-02-11 16:49:14 +03:00
|
|
|
.enable_mdtest = true,
|
2020-05-30 22:09:37 +03:00
|
|
|
.sync = POSIX_Sync,
|
|
|
|
.check_params = POSIX_check_params
|
2011-10-28 03:50:05 +04:00
|
|
|
};
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/***************************** F U N C T I O N S ******************************/
|
|
|
|
|
2020-05-31 14:50:03 +03:00
|
|
|
static aiori_xfer_hint_t * hints = NULL;
|
2020-05-30 20:19:48 +03:00
|
|
|
|
2020-07-21 18:16:13 +03:00
|
|
|
void POSIX_xfer_hints(aiori_xfer_hint_t * params){
|
2020-05-31 14:50:03 +03:00
|
|
|
hints = params;
|
2020-05-30 20:19:48 +03:00
|
|
|
}
|
2011-11-11 07:02:19 +04:00
|
|
|
|
2020-07-21 18:16:13 +03:00
|
|
|
int POSIX_check_params(aiori_mod_opt_t * param){
|
2020-05-30 22:09:37 +03:00
|
|
|
posix_options_t * o = (posix_options_t*) param;
|
|
|
|
if (o->beegfs_chunkSize != -1 && (!ISPOWEROFTWO(o->beegfs_chunkSize) || o->beegfs_chunkSize < (1<<16)))
|
|
|
|
ERR("beegfsChunkSize must be a power of two and >64k");
|
|
|
|
if(o->lustre_stripe_count != -1 || o->lustre_stripe_size != 0)
|
|
|
|
o->lustre_set_striping = 1;
|
2021-02-18 13:40:42 +03:00
|
|
|
if(o->gpuDirect && ! o->direct_io){
|
|
|
|
ERR("GPUDirect required direct I/O to be used!");
|
|
|
|
}
|
|
|
|
#ifndef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
ERR("GPUDirect support is not compiled");
|
|
|
|
}
|
|
|
|
#endif
|
2020-05-30 22:09:37 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
|
|
|
void gpfs_free_all_locks(int fd)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct {
|
|
|
|
gpfsFcntlHeader_t header;
|
|
|
|
gpfsFreeRange_t release;
|
|
|
|
} release_all;
|
|
|
|
release_all.header.totalLength = sizeof(release_all);
|
|
|
|
release_all.header.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
|
|
|
|
release_all.header.fcntlReserved = 0;
|
|
|
|
|
|
|
|
release_all.release.structLen = sizeof(release_all.release);
|
|
|
|
release_all.release.structType = GPFS_FREE_RANGE;
|
|
|
|
release_all.release.start = 0;
|
|
|
|
release_all.release.length = 0;
|
|
|
|
|
|
|
|
rc = gpfs_fcntl(fd, &release_all);
|
|
|
|
if (verbose >= VERBOSE_0 && rc != 0) {
|
2019-08-31 00:11:25 +03:00
|
|
|
EWARNF("gpfs_fcntl(%d, ...) release all locks hint failed.", fd);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
}
|
2020-09-02 12:08:52 +03:00
|
|
|
void gpfs_access_start(int fd, IOR_offset_t length, IOR_offset_t offset, int access)
|
2013-09-26 17:48:50 +04:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct {
|
|
|
|
gpfsFcntlHeader_t header;
|
|
|
|
gpfsAccessRange_t access;
|
|
|
|
} take_locks;
|
|
|
|
|
|
|
|
take_locks.header.totalLength = sizeof(take_locks);
|
|
|
|
take_locks.header.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
|
|
|
|
take_locks.header.fcntlReserved = 0;
|
|
|
|
|
|
|
|
take_locks.access.structLen = sizeof(take_locks.access);
|
|
|
|
take_locks.access.structType = GPFS_ACCESS_RANGE;
|
2020-09-02 12:08:52 +03:00
|
|
|
take_locks.access.start = offset;
|
2013-09-26 17:48:50 +04:00
|
|
|
take_locks.access.length = length;
|
|
|
|
take_locks.access.isWrite = (access == WRITE);
|
|
|
|
|
|
|
|
rc = gpfs_fcntl(fd, &take_locks);
|
|
|
|
if (verbose >= VERBOSE_2 && rc != 0) {
|
2019-10-30 17:43:43 +03:00
|
|
|
EWARNF("gpfs_fcntl(%d, ...) access range hint failed.", fd);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-02 12:08:52 +03:00
|
|
|
void gpfs_access_end(int fd, IOR_offset_t length, IOR_offset_t offset, int access)
|
2013-09-26 17:48:50 +04:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct {
|
|
|
|
gpfsFcntlHeader_t header;
|
|
|
|
gpfsFreeRange_t free;
|
|
|
|
} free_locks;
|
|
|
|
|
|
|
|
|
|
|
|
free_locks.header.totalLength = sizeof(free_locks);
|
|
|
|
free_locks.header.fcntlVersion = GPFS_FCNTL_CURRENT_VERSION;
|
|
|
|
free_locks.header.fcntlReserved = 0;
|
|
|
|
|
|
|
|
free_locks.free.structLen = sizeof(free_locks.free);
|
|
|
|
free_locks.free.structType = GPFS_FREE_RANGE;
|
2020-09-02 12:08:52 +03:00
|
|
|
free_locks.free.start = offset;
|
2013-09-26 17:48:50 +04:00
|
|
|
free_locks.free.length = length;
|
|
|
|
|
|
|
|
rc = gpfs_fcntl(fd, &free_locks);
|
|
|
|
if (verbose >= VERBOSE_2 && rc != 0) {
|
2019-10-30 17:43:43 +03:00
|
|
|
EWARNF("gpfs_fcntl(%d, ...) free range hint failed.", fd);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2017-09-21 18:12:31 +03:00
|
|
|
#ifdef HAVE_BEEGFS_BEEGFS_H
|
|
|
|
|
|
|
|
int mkTempInDir(char* dirPath)
|
|
|
|
{
|
|
|
|
unsigned long len = strlen(dirPath) + 8;
|
|
|
|
char* tmpfilename = (char*)malloc(sizeof (char)*len+1);
|
|
|
|
snprintf(tmpfilename, len, "%s/XXXXXX", dirPath);
|
|
|
|
|
|
|
|
int fd = mkstemp(tmpfilename);
|
|
|
|
unlink(tmpfilename);
|
|
|
|
free(tmpfilename);
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool beegfs_getStriping(char* dirPath, u_int16_t* numTargetsOut, unsigned* chunkSizeOut)
|
|
|
|
{
|
|
|
|
bool retVal = false;
|
|
|
|
|
|
|
|
int fd = mkTempInDir(dirPath);
|
|
|
|
if (fd) {
|
|
|
|
unsigned stripePattern = 0;
|
|
|
|
retVal = beegfs_getStripeInfo(fd, &stripePattern, chunkSizeOut, numTargetsOut);
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool beegfs_isOptionSet(int opt) {
|
|
|
|
return opt != -1;
|
|
|
|
}
|
|
|
|
|
2019-04-29 16:49:57 +03:00
|
|
|
bool beegfs_compatibleFileExists(char* filepath, int numTargets, int chunkSize)
|
|
|
|
{
|
|
|
|
int fd = open(filepath, O_RDWR);
|
|
|
|
|
|
|
|
if (fd == -1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned read_stripePattern = 0;
|
|
|
|
u_int16_t read_numTargets = 0;
|
|
|
|
int read_chunkSize = 0;
|
|
|
|
|
|
|
|
bool retVal = beegfs_getStripeInfo(fd, &read_stripePattern, &read_chunkSize, &read_numTargets);
|
|
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
return retVal && read_numTargets == numTargets && read_chunkSize == chunkSize;
|
|
|
|
}
|
|
|
|
|
2017-09-21 18:12:31 +03:00
|
|
|
/*
|
|
|
|
* Create a file on a BeeGFS file system with striping parameters
|
|
|
|
*/
|
|
|
|
bool beegfs_createFilePath(char* filepath, mode_t mode, int numTargets, int chunkSize)
|
|
|
|
{
|
|
|
|
bool retVal = false;
|
|
|
|
char* dirTmp = strdup(filepath);
|
|
|
|
char* dir = dirname(dirTmp);
|
|
|
|
DIR* parentDirS = opendir(dir);
|
|
|
|
if (!parentDirS) {
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("Failed to get directory: %s", dir);
|
2017-09-21 18:12:31 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int parentDirFd = dirfd(parentDirS);
|
|
|
|
if (parentDirFd < 0)
|
|
|
|
{
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("Failed to get directory descriptor: %s", dir);
|
2017-09-21 18:12:31 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bool isBeegfs = beegfs_testIsBeeGFS(parentDirFd);
|
|
|
|
if (!isBeegfs)
|
|
|
|
{
|
|
|
|
WARN("Not a BeeGFS file system");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( !beegfs_isOptionSet(numTargets)
|
|
|
|
|| !beegfs_isOptionSet(chunkSize)) {
|
|
|
|
u_int16_t defaultNumTargets = 0;
|
|
|
|
unsigned defaultChunkSize = 0;
|
|
|
|
bool haveDefaults = beegfs_getStriping(dir,
|
|
|
|
&defaultNumTargets,
|
|
|
|
&defaultChunkSize);
|
|
|
|
if (!haveDefaults)
|
|
|
|
ERR("Failed to get default BeeGFS striping values");
|
|
|
|
|
|
|
|
numTargets = beegfs_isOptionSet(numTargets) ?
|
|
|
|
numTargets : defaultNumTargets;
|
|
|
|
chunkSize = beegfs_isOptionSet(chunkSize) ?
|
|
|
|
chunkSize : defaultChunkSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* filenameTmp = strdup(filepath);
|
|
|
|
char* filename = basename(filepath);
|
2019-04-29 16:49:57 +03:00
|
|
|
bool isFileCreated = beegfs_compatibleFileExists(filepath, numTargets, chunkSize)
|
|
|
|
|| beegfs_createFile(parentDirFd, filename,
|
|
|
|
mode, numTargets, chunkSize);
|
2017-09-21 18:12:31 +03:00
|
|
|
if (!isFileCreated)
|
|
|
|
ERR("Could not create file");
|
|
|
|
retVal = true;
|
|
|
|
free(filenameTmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(parentDirS);
|
|
|
|
}
|
|
|
|
free(dirTmp);
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
#endif /* HAVE_BEEGFS_BEEGFS_H */
|
|
|
|
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/*
|
2020-07-03 10:09:40 +03:00
|
|
|
* Create and open a file through the POSIX interface.
|
2011-06-17 23:20:43 +04:00
|
|
|
*/
|
2020-05-31 14:11:00 +03:00
|
|
|
aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
int fd_oflag = O_BINARY;
|
2019-08-31 00:11:25 +03:00
|
|
|
int mode = 0664;
|
2021-02-18 13:40:42 +03:00
|
|
|
posix_fd * pfd = safeMalloc(sizeof(posix_fd));
|
2020-05-30 20:19:48 +03:00
|
|
|
posix_options_t * o = (posix_options_t*) param;
|
2019-03-27 23:37:46 +03:00
|
|
|
if (o->direct_io == TRUE){
|
2021-02-18 13:40:42 +03:00
|
|
|
set_o_direct_flag(& fd_oflag);
|
2019-03-27 23:37:46 +03:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2020-05-31 14:11:00 +03:00
|
|
|
return (aiori_fd_t*) 0;
|
2018-10-11 21:58:30 +03:00
|
|
|
|
2020-06-24 12:15:31 +03:00
|
|
|
#ifdef HAVE_LUSTRE_USER
|
2018-12-15 02:26:16 +03:00
|
|
|
/* Add a #define for FASYNC if not available, as it forms part of
|
|
|
|
* the Lustre O_LOV_DELAY_CREATE definition. */
|
|
|
|
#ifndef FASYNC
|
|
|
|
#define FASYNC 00020000 /* fcntl, for BSD compatibility */
|
|
|
|
#endif
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->lustre_set_striping) {
|
2020-07-03 10:09:40 +03:00
|
|
|
/* In the single-shared-file case, task 0 has to create the
|
|
|
|
file with the Lustre striping options before any other
|
|
|
|
processes open the file */
|
2020-05-31 14:50:03 +03:00
|
|
|
if (!hints->filePerProc && rank != 0) {
|
2011-11-12 02:22:17 +04:00
|
|
|
MPI_CHECK(MPI_Barrier(testComm), "barrier error");
|
|
|
|
fd_oflag |= O_RDWR;
|
2021-02-18 13:40:42 +03:00
|
|
|
pfd->fd = open64(testFileName, fd_oflag, mode);
|
|
|
|
if (pfd->fd < 0){
|
2021-01-21 14:06:13 +03:00
|
|
|
ERRF("open64(\"%s\", %d, %#o) failed. Error: %s",
|
|
|
|
testFileName, fd_oflag, mode, strerror(errno));
|
|
|
|
}
|
2011-11-12 02:22:17 +04:00
|
|
|
} else {
|
|
|
|
struct lov_user_md opts = { 0 };
|
|
|
|
|
|
|
|
/* Setup Lustre IOCTL striping pattern structure */
|
|
|
|
opts.lmm_magic = LOV_USER_MAGIC;
|
2020-05-30 22:09:37 +03:00
|
|
|
opts.lmm_stripe_size = o->lustre_stripe_size;
|
|
|
|
opts.lmm_stripe_offset = o->lustre_start_ost;
|
|
|
|
opts.lmm_stripe_count = o->lustre_stripe_count;
|
2011-11-12 02:22:17 +04:00
|
|
|
|
|
|
|
/* File needs to be opened O_EXCL because we cannot set
|
2018-12-15 02:26:16 +03:00
|
|
|
* Lustre striping information on a pre-existing file.*/
|
|
|
|
|
2020-11-26 18:56:34 +03:00
|
|
|
fd_oflag |= O_CREAT | O_EXCL | O_RDWR | O_LOV_DELAY_CREATE;
|
2021-02-18 13:40:42 +03:00
|
|
|
pfd->fd = open64(testFileName, fd_oflag, mode);
|
|
|
|
if (pfd->fd < 0) {
|
2021-01-21 14:06:13 +03:00
|
|
|
ERRF("Unable to open '%s': %s\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
testFileName, strerror(errno));
|
2021-02-18 13:40:42 +03:00
|
|
|
} else if (ioctl(pfd->fd, LL_IOC_LOV_SETSTRIPE, &opts)) {
|
2011-11-12 02:22:17 +04:00
|
|
|
char *errmsg = "stripe already set";
|
|
|
|
if (errno != EEXIST && errno != EALREADY)
|
|
|
|
errmsg = strerror(errno);
|
2021-01-21 14:06:13 +03:00
|
|
|
ERRF("Error on ioctl for '%s' (%d): %s\n",
|
2021-02-18 13:40:42 +03:00
|
|
|
testFileName, pfd->fd, errmsg);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2020-05-31 14:50:03 +03:00
|
|
|
if (!hints->filePerProc)
|
2011-11-12 02:22:17 +04:00
|
|
|
MPI_CHECK(MPI_Barrier(testComm),
|
|
|
|
"barrier error");
|
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
} else {
|
2020-06-24 12:15:31 +03:00
|
|
|
#endif /* HAVE_LUSTRE_USER */
|
2017-09-21 18:12:31 +03:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
fd_oflag |= O_CREAT | O_RDWR;
|
2017-09-21 18:12:31 +03:00
|
|
|
|
|
|
|
#ifdef HAVE_BEEGFS_BEEGFS_H
|
2020-05-30 22:09:37 +03:00
|
|
|
if (beegfs_isOptionSet(o->beegfs_chunkSize)
|
|
|
|
|| beegfs_isOptionSet(o->beegfs_numTargets)) {
|
2017-09-21 18:12:31 +03:00
|
|
|
bool result = beegfs_createFilePath(testFileName,
|
2019-08-31 00:11:25 +03:00
|
|
|
mode,
|
2020-05-30 22:09:37 +03:00
|
|
|
o->beegfs_numTargets,
|
|
|
|
o->beegfs_chunkSize);
|
2017-09-21 18:12:31 +03:00
|
|
|
if (result) {
|
|
|
|
fd_oflag &= ~O_CREAT;
|
|
|
|
} else {
|
|
|
|
EWARN("BeeGFS tuning failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* HAVE_BEEGFS_BEEGFS_H */
|
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
pfd->fd = open64(testFileName, fd_oflag, mode);
|
|
|
|
if (pfd->fd < 0){
|
2021-01-21 14:06:13 +03:00
|
|
|
ERRF("open64(\"%s\", %d, %#o) failed. Error: %s",
|
|
|
|
testFileName, fd_oflag, mode, strerror(errno));
|
|
|
|
}
|
2017-09-21 18:12:31 +03:00
|
|
|
|
2020-06-24 12:15:31 +03:00
|
|
|
#ifdef HAVE_LUSTRE_USER
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->lustre_ignore_locks) {
|
2011-11-12 02:22:17 +04:00
|
|
|
int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK;
|
2021-02-18 13:40:42 +03:00
|
|
|
if (ioctl(pfd->fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1)
|
|
|
|
ERRF("ioctl(%d, LL_IOC_SETFLAGS, ...) failed", pfd->fd);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2020-06-24 12:15:31 +03:00
|
|
|
#endif /* HAVE_LUSTRE_USER */
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
|
|
|
/* in the single shared file case, immediately release all locks, with
|
|
|
|
* the intent that we can avoid some byte range lock revocation:
|
|
|
|
* everyone will be writing/reading from individual regions */
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->gpfs_release_token ) {
|
2021-02-18 13:40:42 +03:00
|
|
|
gpfs_free_all_locks(pfd->fd);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
#endif
|
2021-02-18 13:40:42 +03:00
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
init_cufile(pfd);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return (aiori_fd_t*) pfd;
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2018-10-08 15:30:47 +03:00
|
|
|
/*
|
2020-07-03 10:09:40 +03:00
|
|
|
* Create a file through mknod interface.
|
2018-10-08 15:30:47 +03:00
|
|
|
*/
|
2019-11-04 19:10:36 +03:00
|
|
|
int POSIX_Mknod(char *testFileName)
|
2018-10-08 15:30:47 +03:00
|
|
|
{
|
2019-11-04 19:10:36 +03:00
|
|
|
int ret;
|
2018-10-08 15:30:47 +03:00
|
|
|
|
2019-11-04 19:10:36 +03:00
|
|
|
ret = mknod(testFileName, S_IFREG | S_IRUSR, 0);
|
|
|
|
if (ret < 0)
|
|
|
|
ERR("mknod failed");
|
2018-10-08 15:30:47 +03:00
|
|
|
|
2019-11-04 19:10:36 +03:00
|
|
|
return ret;
|
2018-10-08 15:30:47 +03:00
|
|
|
}
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/*
|
|
|
|
* Open a file through the POSIX interface.
|
|
|
|
*/
|
2020-05-31 14:11:00 +03:00
|
|
|
aiori_fd_t *POSIX_Open(char *testFileName, int flags, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2021-04-26 19:10:47 +03:00
|
|
|
int fd_oflag = O_BINARY;
|
|
|
|
if(flags & IOR_RDONLY){
|
|
|
|
fd_oflag |= O_RDONLY;
|
|
|
|
}else if(flags & IOR_WRONLY){
|
|
|
|
fd_oflag |= O_WRONLY;
|
|
|
|
}else{
|
|
|
|
fd_oflag |= O_RDWR;
|
|
|
|
}
|
2021-02-18 13:40:42 +03:00
|
|
|
posix_fd * pfd = safeMalloc(sizeof(posix_fd));
|
2020-05-30 20:19:48 +03:00
|
|
|
posix_options_t * o = (posix_options_t*) param;
|
2021-02-18 13:40:42 +03:00
|
|
|
if (o->direct_io == TRUE){
|
2011-11-12 02:22:17 +04:00
|
|
|
set_o_direct_flag(&fd_oflag);
|
2021-02-18 13:40:42 +03:00
|
|
|
}
|
2018-10-11 21:58:30 +03:00
|
|
|
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2020-05-31 14:11:00 +03:00
|
|
|
return (aiori_fd_t*) 0;
|
2018-10-11 21:58:30 +03:00
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
pfd->fd = open64(testFileName, fd_oflag);
|
|
|
|
if (pfd->fd < 0)
|
2020-11-02 22:23:13 +03:00
|
|
|
ERRF("open64(\"%s\", %d) failed: %s", testFileName, fd_oflag, strerror(errno));
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2020-06-24 12:15:31 +03:00
|
|
|
#ifdef HAVE_LUSTRE_USER
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->lustre_ignore_locks) {
|
2011-11-12 02:22:17 +04:00
|
|
|
int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK;
|
|
|
|
if (verbose >= VERBOSE_1) {
|
2021-01-21 14:06:13 +03:00
|
|
|
EINFO("** Disabling lustre range locking **\n");
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2021-02-18 13:40:42 +03:00
|
|
|
if (ioctl(pfd->fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1)
|
|
|
|
ERRF("ioctl(%d, LL_IOC_SETFLAGS, ...) failed", pfd->fd);
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
2020-06-24 12:15:31 +03:00
|
|
|
#endif /* HAVE_LUSTRE_USER */
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
2020-05-30 22:09:37 +03:00
|
|
|
if(o->gpfs_release_token) {
|
2021-02-18 13:40:42 +03:00
|
|
|
gpfs_free_all_locks(pfd->fd);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
init_cufile(pfd);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
#endif
|
2021-02-18 13:40:42 +03:00
|
|
|
return (aiori_fd_t*) pfd;
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Write or read access to file using the POSIX interface.
|
|
|
|
*/
|
2020-05-31 14:11:00 +03:00
|
|
|
static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
|
2020-06-10 19:47:07 +03:00
|
|
|
IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
int xferRetries = 0;
|
|
|
|
long long remaining = (long long)length;
|
|
|
|
char *ptr = (char *)buffer;
|
|
|
|
long long rc;
|
|
|
|
int fd;
|
2020-05-30 22:09:37 +03:00
|
|
|
posix_options_t * o = (posix_options_t*) param;
|
2011-11-12 02:22:17 +04:00
|
|
|
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2018-10-11 21:58:30 +03:00
|
|
|
return length;
|
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
posix_fd * pfd = (posix_fd *) file;
|
|
|
|
fd = pfd->fd;
|
2011-11-12 02:22:17 +04:00
|
|
|
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->gpfs_hint_access) {
|
2020-09-02 12:08:52 +03:00
|
|
|
gpfs_access_start(fd, length, offset, access);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
/* seek to offset */
|
2020-06-10 19:47:07 +03:00
|
|
|
if (lseek64(fd, offset, SEEK_SET) == -1)
|
|
|
|
ERRF("lseek64(%d, %lld, SEEK_SET) failed", fd, offset);
|
2021-02-18 13:40:42 +03:00
|
|
|
off_t mem_offset = 0;
|
2011-11-12 02:22:17 +04:00
|
|
|
while (remaining > 0) {
|
|
|
|
/* write/read file */
|
|
|
|
if (access == WRITE) { /* WRITE */
|
|
|
|
if (verbose >= VERBOSE_4) {
|
2021-01-21 14:06:13 +03:00
|
|
|
EINFO("task %d writing to offset %lld\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
rank,
|
2020-06-10 19:47:07 +03:00
|
|
|
offset + length - remaining);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2021-02-18 13:40:42 +03:00
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
rc = cuFileWrite(pfd->cf_handle, ptr, remaining, offset + mem_offset, mem_offset);
|
|
|
|
}else{
|
|
|
|
#endif
|
|
|
|
rc = write(fd, ptr, remaining);
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-12 02:22:17 +04:00
|
|
|
if (rc == -1)
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("write(%d, %p, %lld) failed",
|
|
|
|
fd, (void*)ptr, remaining);
|
2020-05-31 14:50:03 +03:00
|
|
|
if (hints->fsyncPerWrite == TRUE){
|
2020-05-31 14:11:00 +03:00
|
|
|
POSIX_Fsync((aiori_fd_t*) &fd, param);
|
|
|
|
}
|
2011-11-12 02:22:17 +04:00
|
|
|
} else { /* READ or CHECK */
|
|
|
|
if (verbose >= VERBOSE_4) {
|
2021-01-21 14:06:13 +03:00
|
|
|
EINFO("task %d reading from offset %lld\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
rank,
|
2020-06-10 19:47:07 +03:00
|
|
|
offset + length - remaining);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2021-02-18 13:40:42 +03:00
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
rc = cuFileRead(pfd->cf_handle, ptr, remaining, offset + mem_offset, mem_offset);
|
|
|
|
}else{
|
|
|
|
#endif
|
|
|
|
rc = read(fd, ptr, remaining);
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
}
|
|
|
|
#endif
|
2011-11-12 02:22:17 +04:00
|
|
|
if (rc == 0)
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("read(%d, %p, %lld) returned EOF prematurely",
|
|
|
|
fd, (void*)ptr, remaining);
|
2011-11-12 02:22:17 +04:00
|
|
|
if (rc == -1)
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("read(%d, %p, %lld) failed",
|
|
|
|
fd, (void*)ptr, remaining);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
|
|
|
if (rc < remaining) {
|
2021-01-21 14:06:13 +03:00
|
|
|
EWARNF("task %d, partial %s, %lld of %lld bytes at offset %lld\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
rank,
|
|
|
|
access == WRITE ? "write()" : "read()",
|
|
|
|
rc, remaining,
|
2020-06-10 19:47:07 +03:00
|
|
|
offset + length - remaining);
|
2021-01-21 14:06:13 +03:00
|
|
|
if (xferRetries > MAX_RETRY || hints->singleXferAttempt)
|
2011-11-12 02:22:17 +04:00
|
|
|
ERR("too many retries -- aborting");
|
|
|
|
}
|
|
|
|
assert(rc >= 0);
|
|
|
|
assert(rc <= remaining);
|
|
|
|
remaining -= rc;
|
|
|
|
ptr += rc;
|
2021-02-18 13:40:42 +03:00
|
|
|
mem_offset += rc;
|
2011-11-12 02:22:17 +04:00
|
|
|
xferRetries++;
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
2013-09-26 17:48:50 +04:00
|
|
|
#ifdef HAVE_GPFS_FCNTL_H
|
2020-05-30 22:09:37 +03:00
|
|
|
if (o->gpfs_hint_access) {
|
2020-09-02 12:08:52 +03:00
|
|
|
gpfs_access_end(fd, length, offset, access);
|
2013-09-26 17:48:50 +04:00
|
|
|
}
|
|
|
|
#endif
|
2011-11-12 02:22:17 +04:00
|
|
|
return (length);
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2021-02-18 13:40:42 +03:00
|
|
|
void POSIX_Fsync(aiori_fd_t *afd, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2021-02-18 13:40:42 +03:00
|
|
|
int fd = ((posix_fd*) afd)->fd;
|
|
|
|
if (fsync(fd) != 0)
|
|
|
|
EWARNF("fsync(%d) failed", fd);
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2019-09-01 17:47:42 +03:00
|
|
|
|
2020-07-21 18:16:13 +03:00
|
|
|
void POSIX_Sync(aiori_mod_opt_t * param)
|
2019-09-01 17:47:42 +03:00
|
|
|
{
|
|
|
|
int ret = system("sync");
|
|
|
|
if (ret != 0){
|
|
|
|
FAIL("Error executing the sync command, ensure it exists.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/*
|
|
|
|
* Close a file through the POSIX interface.
|
|
|
|
*/
|
2021-02-18 13:40:42 +03:00
|
|
|
void POSIX_Close(aiori_fd_t *afd, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2018-10-11 21:58:30 +03:00
|
|
|
return;
|
2021-02-18 13:40:42 +03:00
|
|
|
posix_options_t * o = (posix_options_t*) param;
|
|
|
|
int fd = ((posix_fd*) afd)->fd;
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
if(o->gpuDirect){
|
|
|
|
cuFileHandleDeregister(((posix_fd*) afd)->cf_handle);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (close(fd) != 0){
|
|
|
|
ERRF("close(%d) failed", fd);
|
|
|
|
}
|
|
|
|
free(afd);
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Delete a file through the POSIX interface.
|
|
|
|
*/
|
2020-05-31 13:58:34 +03:00
|
|
|
void POSIX_Delete(char *testFileName, aiori_mod_opt_t * param)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2018-10-11 21:58:30 +03:00
|
|
|
return;
|
|
|
|
if (unlink(testFileName) != 0){
|
2020-06-24 13:10:42 +03:00
|
|
|
EWARNF("[RANK %03d]: unlink() of file \"%s\" failed", rank, testFileName);
|
2018-10-11 21:58:30 +03:00
|
|
|
}
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2021-01-21 17:10:23 +03:00
|
|
|
int POSIX_Rename(const char * oldfile, const char * newfile, aiori_mod_opt_t * module_options){
|
|
|
|
if(hints->dryRun)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if(rename(oldfile, newfile) != 0){
|
|
|
|
EWARNF("[RANK %03d]: rename() of file \"%s\" to \"%s\" failed", rank, oldfile, newfile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/*
|
|
|
|
* Use POSIX stat() to return aggregate file size.
|
|
|
|
*/
|
2020-06-30 14:33:56 +03:00
|
|
|
IOR_offset_t POSIX_GetFileSize(aiori_mod_opt_t * test, char *testFileName)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2020-05-31 14:50:03 +03:00
|
|
|
if(hints->dryRun)
|
2018-10-11 21:58:30 +03:00
|
|
|
return 0;
|
2011-11-12 02:22:17 +04:00
|
|
|
struct stat stat_buf;
|
|
|
|
IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
|
|
|
|
|
|
|
|
if (stat(testFileName, &stat_buf) != 0) {
|
2019-08-31 00:11:25 +03:00
|
|
|
ERRF("stat(\"%s\", ...) failed", testFileName);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
|
|
|
aggFileSizeFromStat = stat_buf.st_size;
|
|
|
|
|
|
|
|
return (aggFileSizeFromStat);
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2021-02-18 13:40:42 +03:00
|
|
|
|
|
|
|
void POSIX_Initialize(aiori_mod_opt_t * options){
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
CUfileError_t err = cuFileDriverOpen();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void POSIX_Finalize(aiori_mod_opt_t * options){
|
|
|
|
#ifdef HAVE_GPU_DIRECT
|
|
|
|
CUfileError_t err = cuFileDriverClose();
|
|
|
|
#endif
|
|
|
|
}
|