IOR
aiori-PMDK.c
Go to the documentation of this file.
1 /******************************************************************************\
2  * *
3  * Copyright (c) 2019 EPCC, The University of Edinburgh *
4  * Written by Adrian Jackson a.jackson@epcc.ed.ac.uk *
5  * *
6  *******************************************************************************
7  * *
8  * *
9  * This file implements the abstract I/O interface for the low-level PMDK API *
10  * *
11 \******************************************************************************/
12 
13 
14 #include "aiori.h" /* abstract IOR interface */
15 #include <errno.h> /* sys_errlist */
16 #include <stdio.h> /* only for fprintf() */
17 #include <stdlib.h>
18 #include <sys/stat.h>
19 #include <libpmem.h>
20 
21 
22 
23 static option_help options [] = {
25 };
26 
27 
28 /**************************** P R O T O T Y P E S *****************************/
29 
30 static option_help * PMDK_options();
31 static aiori_fd_t *PMDK_Create(char *,int iorflags, aiori_mod_opt_t *);
32 static aiori_fd_t *PMDK_Open(char *, int iorflags, aiori_mod_opt_t *);
34 static void PMDK_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
35 static void PMDK_Close(aiori_fd_t *, aiori_mod_opt_t *);
36 static void PMDK_Delete(char *, aiori_mod_opt_t *);
38 
40 
41 static void PMDK_xfer_hints(aiori_xfer_hint_t * params){
42  hints = params;
43 }
44 
45 /************************** D E C L A R A T I O N S ***************************/
46 
47 extern int errno;
48 extern int rank;
49 extern int rankOffset;
50 extern int verbose;
51 extern MPI_Comm testComm;
52 
54  .name = "PMDK",
55  .name_legacy = NULL,
56  .create = PMDK_Create,
57  .open = PMDK_Open,
58  .xfer = PMDK_Xfer,
59  .close = PMDK_Close,
60  .delete = PMDK_Delete,
61  .get_version = aiori_get_version,
62  .fsync = PMDK_Fsync,
63  .xfer_hints = PMDK_xfer_hints,
64  .get_file_size = PMDK_GetFileSize,
65  .statfs = aiori_posix_statfs,
66  .mkdir = aiori_posix_mkdir,
67  .rmdir = aiori_posix_rmdir,
68  .access = aiori_posix_access,
69  .stat = aiori_posix_stat,
70  .get_options = PMDK_options,
71  .enable_mdtest = false,
72 };
73 
74 
75 /***************************** F U N C T I O N S ******************************/
76 
77 /******************************************************************************/
78 
80  return options;
81 }
82 
83 
84 /*
85  * Create and open a memory space through the PMDK interface.
86  */
87 static aiori_fd_t *PMDK_Create(char * testFileName, int iorflags, aiori_mod_opt_t * param){
88  char *pmemaddr = NULL;
89  int is_pmem;
90  size_t mapped_len;
91  size_t open_length;
92 
93  if(! hints->filePerProc){
94  fprintf(stdout, "\nPMDK functionality can only be used with filePerProc functionality\n");
95  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
96  }
97 
98  open_length = hints->blockSize * hints->segmentCount;
99 
100  if((pmemaddr = pmem_map_file(testFileName, open_length,
101  PMEM_FILE_CREATE|PMEM_FILE_EXCL,
102  0666, &mapped_len, &is_pmem)) == NULL) {
103  fprintf(stdout, "\nFailed to pmem_map_file for filename: %s in IOR_Create_PMDK\n", testFileName);
104  perror("pmem_map_file");
105  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
106  }
107 
108  if(!is_pmem){
109  fprintf(stdout, "\n is_pmem is %d\n",is_pmem);
110  fprintf(stdout, "\npmem_map_file thinks the hardware being used is not pmem\n");
111  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
112  }
113 
114 
115 
116  return((void *)pmemaddr);
117 } /* PMDK_Create() */
118 
119 
120 /******************************************************************************/
121 /*
122  * Open a memory space through the PMDK interface.
123  */
124 static aiori_fd_t *PMDK_Open(char * testFileName,int iorflags, aiori_mod_opt_t * param){
125 
126  char *pmemaddr = NULL;
127  int is_pmem;
128  size_t mapped_len;
129  size_t open_length;
130 
131  if(!hints->filePerProc){
132  fprintf(stdout, "\nPMDK functionality can only be used with filePerProc functionality\n");
133  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
134  }
135 
136  open_length = hints->blockSize * hints->segmentCount;
137 
138  if((pmemaddr = pmem_map_file(testFileName, 0,
139  PMEM_FILE_EXCL,
140  0666, &mapped_len, &is_pmem)) == NULL) {
141  fprintf(stdout, "\nFailed to pmem_map_file for filename: %s\n in IOR_Open_PMDK", testFileName);
142  perror("pmem_map_file");
143  fprintf(stdout, "\n %ld %ld\n",open_length, mapped_len);
144  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
145  }
146 
147  if(!is_pmem){
148  fprintf(stdout, "pmem_map_file thinks the hardware being used is not pmem\n");
149  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
150  }
151 
152  return((void *)pmemaddr);
153 } /* PMDK_Open() */
154 
155 
156 /******************************************************************************/
157 /*
158  * Write or read access to a memory space created with PMDK. Include drain/flush functionality.
159  */
160 
161 static IOR_offset_t PMDK_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
163  int xferRetries = 0;
164  long long remaining = (long long)length;
165  char * ptr = (char *)buffer;
166  long long rc;
167  long long i;
168  long long offset_size;
169 
170  offset_size = offset;
171 
172  if(access == WRITE){
173  if(hints->fsyncPerWrite){
174  pmem_memcpy_nodrain(&file[offset_size], ptr, length);
175  }else{
176  pmem_memcpy_persist(&file[offset_size], ptr, length);
177  }
178  }else{
179  memcpy(ptr, &file[offset_size], length);
180  }
181 
182  return(length);
183 } /* PMDK_Xfer() */
184 
185 
186 /******************************************************************************/
187 /*
188  * Perform fsync().
189  */
190 
191 static void PMDK_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param)
192 {
193  pmem_drain();
194 } /* PMDK_Fsync() */
195 
196 
197 /******************************************************************************/
198 /*
199  * Stub for close functionality that is not required for PMDK
200  */
201 
202 static void PMDK_Close(aiori_fd_t *fd, aiori_mod_opt_t * param){
203  size_t open_length;
204  open_length = hints->transferSize;
205  pmem_unmap(fd, open_length);
206 } /* PMDK_Close() */
207 
208 
209 /******************************************************************************/
210 /*
211  * Delete the file backing a memory space through PMDK
212  */
213 
214 static void PMDK_Delete(char *testFileName, aiori_mod_opt_t * param)
215 {
216  char errmsg[256];
217  sprintf(errmsg,"[RANK %03d]:cannot delete file %s\n",rank,testFileName);
218  if (unlink(testFileName) != 0) WARN(errmsg);
219 } /* PMDK_Delete() */
220 
221 /******************************************************************************/
222 /*
223  * Use POSIX stat() to return aggregate file size.
224  */
225 
227  char * testFileName)
228 {
229  struct stat stat_buf;
230  IOR_offset_t aggFileSizeFromStat,
231  tmpMin, tmpMax, tmpSum;
232  if (hints->filePerProc == FALSE) {
233  fprintf(stdout, "\nPMDK functionality can only be used with filePerProc functionality\n");
234  MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
235  }
236 
237  if (stat(testFileName, &stat_buf) != 0) {
238  ERR("cannot get status of written file");
239  }
240  aggFileSizeFromStat = stat_buf.st_size;
241 
242  return(aggFileSizeFromStat);
243 } /* PMDK_GetFileSize() */
MPI_Comm testComm
Definition: utilities.c:71
#define LAST_OPTION
Definition: option.h:39
IOR_offset_t segmentCount
Definition: aiori.h:71
int verbose
Definition: utilities.c:70
CURLcode rc
Definition: aiori-S3-4c.c:111
int errno
IOR_offset_t blockSize
Definition: aiori.h:72
int rank
Definition: utilities.c:68
static option_help options[]
Definition: aiori-PMDK.c:23
#define MPI_CHECK(MPI_STATUS, MSG)
Definition: aiori-debug.h:127
#define WRITE
Definition: iordef.h:86
int aiori_posix_stat(const char *path, struct stat *buf, aiori_mod_opt_t *module_options)
Definition: aiori.c:227
char * aiori_get_version()
Definition: aiori.c:232
static void PMDK_xfer_hints(aiori_xfer_hint_t *params)
Definition: aiori-PMDK.c:41
static IOR_offset_t PMDK_Xfer(int, aiori_fd_t *, IOR_size_t *, IOR_offset_t, IOR_offset_t, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:161
static void PMDK_Fsync(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:191
#define WARN(MSG)
Definition: aiori-debug.h:32
int rankOffset
Definition: utilities.c:69
static aiori_fd_t * PMDK_Create(char *, int iorflags, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:87
Definition: ior.h:56
IOR_offset_t transferSize
Definition: aiori.h:73
int aiori_posix_access(const char *path, int mode, aiori_mod_opt_t *module_options)
Definition: aiori.c:222
static aiori_xfer_hint_t * hints
Definition: aiori-PMDK.c:39
#define FALSE
Definition: iordef.h:62
long long int IOR_size_t
Definition: iordef.h:110
int aiori_posix_rmdir(const char *path, aiori_mod_opt_t *module_options)
Definition: aiori.c:217
static void PMDK_Close(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:202
int aiori_posix_mkdir(const char *path, mode_t mode, aiori_mod_opt_t *module_options)
Definition: aiori.c:212
static aiori_fd_t * PMDK_Open(char *, int iorflags, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:124
int aiori_posix_statfs(const char *path, ior_aiori_statfs_t *stat_buf, aiori_mod_opt_t *module_options)
Definition: aiori.c:166
#define ERR(MSG)
Definition: aiori-debug.h:92
int fsyncPerWrite
Definition: aiori.h:70
char * name
Definition: aiori.h:88
int filePerProc
Definition: aiori.h:65
static void PMDK_Delete(char *, aiori_mod_opt_t *)
Definition: aiori-PMDK.c:214
long long int IOR_offset_t
Definition: iordef.h:109
static option_help * PMDK_options()
Definition: aiori-PMDK.c:79
ior_aiori_t pmdk_aiori
Definition: aiori-PMDK.c:53
#define NULL
Definition: iordef.h:70
static IOR_offset_t PMDK_GetFileSize(aiori_mod_opt_t *, char *)
Definition: aiori-PMDK.c:226