IOR
aiori-S3-libs3.c
Go to the documentation of this file.
1 /*
2 * S3 implementation using the newer libs3
3 * https://github.com/bji/libs3
4 * Use one object per file chunk
5 */
6 
7 #ifdef HAVE_CONFIG_H
8 # include "config.h"
9 #endif
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <time.h>
15 
16 #include <libs3.h>
17 
18 #include "ior.h"
19 #include "aiori.h"
20 #include "aiori-debug.h"
21 #include "utilities.h"
22 
23 
25 
26 static void s3_xfer_hints(aiori_xfer_hint_t * params){
27  hints = params;
28 }
29 
30 /************************** O P T I O N S *****************************/
31 typedef struct {
33  char * access_key;
34  char * secret_key;
35  char * host;
36  char * bucket_prefix;
39  char * authRegion;
40 
41  int timeout;
44  int use_ssl;
45  S3BucketContext bucket_context;
46  S3Protocol s3_protocol;
47 } s3_options_t;
48 
49 static option_help * S3_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){
50  s3_options_t * o = malloc(sizeof(s3_options_t));
51  if (init_values != NULL){
52  memcpy(o, init_values, sizeof(s3_options_t));
53  }else{
54  memset(o, 0, sizeof(s3_options_t));
55  }
56 
57  *init_backend_options = (aiori_mod_opt_t*) o;
58  o->bucket_prefix = "ior";
59  o->bucket_prefix_cur = "b";
60 
61  option_help h [] = {
62  {0, "S3-libs3.bucket-per-file", "Use one bucket to map one file/directory, otherwise one bucket is used to store all dirs/files.", OPTION_FLAG, 'd', & o->bucket_per_file},
63  {0, "S3-libs3.bucket-name-prefix", "The prefix of the bucket(s).", OPTION_OPTIONAL_ARGUMENT, 's', & o->bucket_prefix},
64  {0, "S3-libs3.dont-suffix-bucket", "By default a hash will be added to the bucket name to increase uniqueness, this disables the option.", OPTION_FLAG, 'd', & o->dont_suffix },
65  {0, "S3-libs3.s3-compatible", "to be selected when using S3 compatible storage", OPTION_FLAG, 'd', & o->s3_compatible },
66  {0, "S3-libs3.use-ssl", "used to specify that SSL is needed for the connection", OPTION_FLAG, 'd', & o->use_ssl },
67  {0, "S3-libs3.host", "The host optionally followed by:port. Or specify a list of hosts separated by [ ,;] to be used in a round robin fashion by the MPI ranks.", OPTION_OPTIONAL_ARGUMENT, 's', & o->host},
68  {0, "S3-libs3.secret-key", "The secret key.", OPTION_OPTIONAL_ARGUMENT, 's', & o->secret_key},
69  {0, "S3-libs3.access-key", "The access key.", OPTION_OPTIONAL_ARGUMENT, 's', & o->access_key},
70  {0, "S3-libs3.region", "The region used for the authorization signature.", OPTION_OPTIONAL_ARGUMENT, 's', & o->authRegion},
71  {0, "S3-libs3.location", "The bucket geographic location.", OPTION_OPTIONAL_ARGUMENT, 's', & o->locationConstraint},
73  };
74  option_help * help = malloc(sizeof(h));
75  memcpy(help, h, sizeof(h));
76  return help;
77 }
78 
79 static void def_file_name(s3_options_t * o, char * out_name, char const * path){
80  if(o->bucket_per_file){
81  out_name += sprintf(out_name, "%s-", o->bucket_prefix_cur);
82  }
83  // duplicate path except "/"
84  while(*path != 0){
85  char c = *path;
86  if(((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') )){
87  *out_name = *path;
88  out_name++;
89  }else if(c >= 'A' && c <= 'Z'){
90  *out_name = *path + ('a' - 'A');
91  out_name++;
92  }else if(c == '/'){
93  *out_name = '_';
94  out_name++;
95  }else{
96  // encode special characters
97  *out_name = 'a' + (c / 26);
98  out_name++;
99  *out_name = 'a' + (c % 26);
100  out_name++;
101  }
102  path++;
103  }
104  *out_name = 'b';
105  out_name++;
106  *out_name = '\0';
107 }
108 
109 static void def_bucket_name(s3_options_t * o, char * out_name, char const * path){
110  // S3_MAX_BUCKET_NAME_SIZE
111  if(o->bucket_per_file){
112  out_name += sprintf(out_name, "%s-", o->bucket_prefix_cur);
113  }
114  // duplicate path except "/"
115  while(*path != 0){
116  char c = *path;
117  if(((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') )){
118  *out_name = *path;
119  out_name++;
120  }else if(c >= 'A' && c <= 'Z'){
121  *out_name = *path + ('a' - 'A');
122  out_name++;
123  }
124  path++;
125  }
126  *out_name = '\0';
127 
128  // S3Status S3_validate_bucket_name(const char *bucketName, S3UriStyle uriStyle);
129 }
130 
133  int64_t size;
134 };
135 
136 static S3Status s3status = S3StatusInterrupted;
137 static S3ErrorDetails s3error = {NULL};
138 
139 static S3Status responsePropertiesCallback(const S3ResponseProperties *properties, void *callbackData){
140  s3status = S3StatusOK;
141  return s3status;
142 }
143 
144 static void responseCompleteCallback(S3Status status, const S3ErrorDetails *error, void *callbackData) {
145  s3status = status;
146  if (error == NULL){
147  s3error.message = NULL;
148  }else{
149  s3error = *error;
150  }
151  return;
152 }
153 
154 #define CHECK_ERROR(p) \
155 if (s3status != S3StatusOK){ \
156  WARNF("S3 %s:%d (path:%s) \"%s\": %s %s", __FUNCTION__, __LINE__, p, S3_get_status_name(s3status), s3error.message, s3error.furtherDetails ? s3error.furtherDetails : ""); \
157 }
158 
159 
161 
162 static char * S3_getVersion()
163 {
164  return "0.5";
165 }
166 
168 {
169  // Not needed
170 }
171 
172 
174 {
175  // Not needed
176 }
177 
178 static S3Status S3ListResponseCallback(const char *ownerId, const char *ownerDisplayName, const char *bucketName, int64_t creationDateSeconds, void *callbackData){
179  uint64_t * count = (uint64_t*) callbackData;
180  *count += 1;
181  return S3StatusOK;
182 }
183 
185 
186 static int S3_statfs (const char * path, ior_aiori_statfs_t * stat, aiori_mod_opt_t * options){
187  stat->f_bsize = 1;
188  stat->f_blocks = 1;
189  stat->f_bfree = 1;
190  stat->f_bavail = 1;
191  stat->f_ffree = 1;
192  s3_options_t * o = (s3_options_t*) options;
193 
194  // use the number of bucket as files
195  uint64_t buckets = 0;
196  S3_list_service(o->s3_protocol, o->access_key, o->secret_key, NULL, o->host,
197  o->authRegion, NULL, o->timeout, & listhandler, & buckets);
198  stat->f_files = buckets;
200 
201  return 0;
202 }
203 
204 static S3Status S3multipart_handler(const char *upload_id, void *callbackData){
205  *((char const**)(callbackData)) = upload_id;
206  return S3StatusOK;
207 }
208 
210 
211 typedef struct{
212  char * object;
213 } S3_fd_t;
214 
215 static int putObjectDataCallback(int bufferSize, char *buffer, void *callbackData){
216  struct data_handling * dh = (struct data_handling *) callbackData;
217  const int64_t size = dh->size > bufferSize ? bufferSize : dh->size;
218  if(size == 0) return 0;
219  memcpy(buffer, dh->buf, size);
220  dh->buf = (IOR_size_t*) ((char*)(dh->buf) + size);
221  dh->size -= size;
222 
223  return size;
224 }
225 
227 
228 static aiori_fd_t *S3_Create(char *path, int iorflags, aiori_mod_opt_t * options)
229 {
230  char * upload_id;
231  s3_options_t * o = (s3_options_t*) options;
232  char p[FILENAME_MAX];
233  def_file_name(o, p, path);
234 
235 
236  if(iorflags & IOR_CREAT){
237  if(o->bucket_per_file){
238  S3_create_bucket(o->s3_protocol, o->access_key, o->secret_key, NULL, o->host, p, o->authRegion, S3CannedAclPrivate, o->locationConstraint, NULL, o->timeout, & responseHandler, NULL);
239  }else{
240  struct data_handling dh = { .buf = NULL, .size = 0 };
241  S3_put_object(& o->bucket_context, p, 0, NULL, NULL, o->timeout, &putObjectHandler, & dh);
242  }
243  if (s3status != S3StatusOK){
244  CHECK_ERROR(p);
245  return NULL;
246  }
247  }
248 
249  S3_fd_t * fd = malloc(sizeof(S3_fd_t));
250  fd->object = strdup(p);
251  return (aiori_fd_t*) fd;
252 }
253 
254 
255 static S3Status statResponsePropertiesCallback(const S3ResponseProperties *properties, void *callbackData){
256  // check the size
257  struct stat *buf = (struct stat*) callbackData;
258  if(buf != NULL){
259  buf->st_size = properties->contentLength;
260  buf->st_mtime = properties->lastModified;
261  }
262  s3status = S3StatusOK;
263  return s3status;
264 }
265 
267 
268 static aiori_fd_t *S3_Open(char *path, int flags, aiori_mod_opt_t * options)
269 {
270  if(flags & IOR_CREAT){
271  return S3_Create(path, flags, options);
272  }
273  if(flags & IOR_WRONLY){
274  WARN("S3 IOR_WRONLY is not supported");
275  }
276  if(flags & IOR_RDWR){
277  WARN("S3 IOR_RDWR is not supported");
278  }
279 
280  s3_options_t * o = (s3_options_t*) options;
281  char p[FILENAME_MAX];
282  def_file_name(o, p, path);
283 
284  if (o->bucket_per_file){
285  S3_test_bucket(o->s3_protocol, S3UriStylePath, o->access_key, o->secret_key,
286  NULL, o->host, p, o->authRegion, 0, NULL,
287  NULL, o->timeout, & responseHandler, NULL);
288  }else{
289  struct stat buf;
290  S3_head_object(& o->bucket_context, p, NULL, o->timeout, & statResponseHandler, & buf);
291  }
292  if (s3status != S3StatusOK){
293  CHECK_ERROR(p);
294  return NULL;
295  }
296 
297  S3_fd_t * fd = malloc(sizeof(S3_fd_t));
298  fd->object = strdup(p);
299  return (aiori_fd_t*) fd;
300 }
301 
302 static S3Status getObjectDataCallback(int bufferSize, const char *buffer, void *callbackData){
303  struct data_handling * dh = (struct data_handling *) callbackData;
304  const int64_t size = dh->size > bufferSize ? bufferSize : dh->size;
305  memcpy(dh->buf, buffer, size);
306  dh->buf = (IOR_size_t*) ((char*)(dh->buf) + size);
307  dh->size -= size;
308 
309  return S3StatusOK;
310 }
311 
313 
314 static IOR_offset_t S3_Xfer(int access, aiori_fd_t * afd, IOR_size_t * buffer, IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t * options){
315  S3_fd_t * fd = (S3_fd_t *) afd;
316  struct data_handling dh = { .buf = buffer, .size = length };
317 
318  s3_options_t * o = (s3_options_t*) options;
319  char p[FILENAME_MAX];
320 
321  if(o->bucket_per_file){
322  o->bucket_context.bucketName = fd->object;
323  if(offset != 0){
324  sprintf(p, "%ld-%ld", (long) offset, (long) length);
325  }else{
326  sprintf(p, "0");
327  }
328  }else{
329  if(offset != 0){
330  sprintf(p, "%s-%ld-%ld", fd->object, (long) offset, (long) length);
331  }else{
332  sprintf(p, "%s", fd->object);
333  }
334  }
335  if(access == WRITE){
336  S3_put_object(& o->bucket_context, p, length, NULL, NULL, o->timeout, &putObjectHandler, & dh);
337  }else{
338  S3_get_object(& o->bucket_context, p, NULL, 0, length, NULL, o->timeout, &getObjectHandler, & dh);
339  }
340  if (! o->s3_compatible){
341  CHECK_ERROR(p);
342  }
343  return length;
344 }
345 
346 
348 {
349  S3_fd_t * fd = (S3_fd_t *) afd;
350  free(fd->object);
351  free(afd);
352 }
353 
354 typedef struct {
355  int status; // do not reorder!
358  char const *nextMarker;
359 } s3_delete_req;
360 
361 S3Status list_delete_cb(int isTruncated, const char *nextMarker, int contentsCount, const S3ListBucketContent *contents, int commonPrefixesCount, const char **commonPrefixes, void *callbackData){
362  s3_delete_req * req = (s3_delete_req*) callbackData;
363  for(int i=0; i < contentsCount; i++){
364  S3_delete_object(& req->o->bucket_context, contents[i].key, NULL, req->o->timeout, & responseHandler, NULL);
365  }
366  req->truncated = isTruncated;
367  if(isTruncated){
368  req->nextMarker = nextMarker;
369  }
370  return S3StatusOK;
371 }
372 
374 
375 static void S3_Delete(char *path, aiori_mod_opt_t * options)
376 {
377  s3_options_t * o = (s3_options_t*) options;
378  char p[FILENAME_MAX];
379  def_file_name(o, p, path);
380 
381 
382  if(o->bucket_per_file){
383  o->bucket_context.bucketName = p;
384  s3_delete_req req = {0, o, 0, NULL};
385  do{
386  S3_list_bucket(& o->bucket_context, NULL, req.nextMarker, NULL, INT_MAX, NULL, o->timeout, & list_delete_handler, & req);
387  }while(req.truncated);
388  S3_delete_bucket(o->s3_protocol, S3UriStylePath, o->access_key, o->secret_key, NULL, o->host, p, o->authRegion, NULL, o->timeout, & responseHandler, NULL);
389  }else{
390  char * del_heuristics = getenv("S3LIB_DELETE_HEURISTICS");
391  if(del_heuristics){
392  struct stat buf;
393  S3_head_object(& o->bucket_context, p, NULL, o->timeout, & statResponseHandler, & buf);
394  if(s3status != S3StatusOK){
395  // As the file does not exist, can return safely
396  CHECK_ERROR(p);
397  return;
398  }
399  int threshold = atoi(del_heuristics);
400  if (buf.st_size > threshold){
401  // there may exist fragments, so try to delete them
402  s3_delete_req req = {0, o, 0, NULL};
403  do{
404  S3_list_bucket(& o->bucket_context, p, req.nextMarker, NULL, INT_MAX, NULL, o->timeout, & list_delete_handler, & req);
405  }while(req.truncated);
406  }
407  S3_delete_object(& o->bucket_context, p, NULL, o->timeout, & responseHandler, NULL);
408  }else{
409  // Regular deletion, must remove all created fragments
410  S3_delete_object(& o->bucket_context, p, NULL, o->timeout, & responseHandler, NULL);
411  if(s3status != S3StatusOK){
412  // As the file does not exist, can return savely
413  CHECK_ERROR(p);
414  return;
415  }
416  s3_delete_req req = {0, o, 0, NULL};
417  do{
418  S3_list_bucket(& o->bucket_context, p, req.nextMarker, NULL, INT_MAX, NULL, o->timeout, & list_delete_handler, & req);
419  }while(req.truncated);
420  }
421  }
422  CHECK_ERROR(p);
423 }
424 
425 static int S3_mkdir (const char *path, mode_t mode, aiori_mod_opt_t * options){
426  s3_options_t * o = (s3_options_t*) options;
427  char p[FILENAME_MAX];
428  def_bucket_name(o, p, path);
429 
430 
431  if (o->bucket_per_file){
432  S3_create_bucket(o->s3_protocol, o->access_key, o->secret_key, NULL, o->host, p, o->authRegion, S3CannedAclPrivate, o->locationConstraint, NULL, o->timeout, & responseHandler, NULL);
433  CHECK_ERROR(p);
434  return 0;
435  }else{
436  struct data_handling dh = { .buf = NULL, .size = 0 };
437  S3_put_object(& o->bucket_context, p, 0, NULL, NULL, o->timeout, & putObjectHandler, & dh);
438  if (! o->s3_compatible){
439  CHECK_ERROR(p);
440  }
441  return 0;
442  }
443 }
444 
445 static int S3_rmdir (const char *path, aiori_mod_opt_t * options){
446  s3_options_t * o = (s3_options_t*) options;
447  char p[FILENAME_MAX];
448 
449  def_bucket_name(o, p, path);
450  if (o->bucket_per_file){
451  S3_delete_bucket(o->s3_protocol, S3UriStylePath, o->access_key, o->secret_key, NULL, o->host, p, o->authRegion, NULL, o->timeout, & responseHandler, NULL);
452  CHECK_ERROR(p);
453  return 0;
454  }else{
455  S3_delete_object(& o->bucket_context, p, NULL, o->timeout, & responseHandler, NULL);
456  CHECK_ERROR(p);
457  return 0;
458  }
459 }
460 
461 static int S3_stat(const char *path, struct stat *buf, aiori_mod_opt_t * options){
462  s3_options_t * o = (s3_options_t*) options;
463  char p[FILENAME_MAX];
464  def_file_name(o, p, path);
465  memset(buf, 0, sizeof(struct stat));
466  // TODO count the individual file fragment sizes together
467  if (o->bucket_per_file){
468  S3_test_bucket(o->s3_protocol, S3UriStylePath, o->access_key, o->secret_key,
469  NULL, o->host, p, o->authRegion, 0, NULL,
470  NULL, o->timeout, & responseHandler, NULL);
471  }else{
472  S3_head_object(& o->bucket_context, p, NULL, o->timeout, & statResponseHandler, buf);
473  }
474  if (s3status != S3StatusOK){
475  return -1;
476  }
477  return 0;
478 }
479 
480 static int S3_access (const char *path, int mode, aiori_mod_opt_t * options){
481  struct stat buf;
482  return S3_stat(path, & buf, options);
483 }
484 
485 static IOR_offset_t S3_GetFileSize(aiori_mod_opt_t * options, char *testFileName)
486 {
487  struct stat buf;
488  if(S3_stat(testFileName, & buf, options) != 0) return -1;
489  return buf.st_size;
490 }
491 
492 
494  s3_options_t * o = (s3_options_t*) options;
495  if(o->access_key == NULL){
496  o->access_key = "";
497  }
498  if(o->secret_key == NULL){
499  o->secret_key = "";
500  }
501  if(o->host == NULL){
502  WARN("The S3 hostname should be specified");
503  }
504  return 0;
505 }
506 
508  s3_options_t * o = (s3_options_t*) options;
509 
510  /* parse list of hostnames into specific host for this rank;
511  this cannot be done during S3_options() because this happens before MPI_Init() */
512  if ( o->host != NULL ) {
513 
514  const char* delimiters= " ,;";
515 
516  int num_hosts = 0;
517  char* r= strtok(o->host, delimiters);
518  while (r != NULL) {
519  num_hosts++;
520  r= strtok(NULL, delimiters);
521  }
522 
523  if (num_hosts > 1) {
524 
525  int i= rank % num_hosts;
526 
527  /* set o->host to the i'th piece separated by '\0' */
528  char* next= o->host;
529  while (i > 0) {
530 
531  next= strchr(next, '\0');
532  next++;
533  i--;
534  }
535  o->host= next;
536  }
537  }
538 
539  int ret = S3_initialize(NULL, S3_INIT_ALL, o->host);
540  if(ret != S3StatusOK)
541  FAIL("Could not initialize S3 library");
542 
543  // create a bucket id based on access-key using a trivial checksumming
544  if(! o->dont_suffix){
545  uint64_t c = 0;
546  char * r = o->access_key;
547  for(uint64_t pos = 1; (*r) != '\0' ; r++, pos*=10) {
548  c += (*r) * pos;
549  }
550  int count = snprintf(NULL, 0, "%s%lu", o->bucket_prefix, c % 1000);
551  char * old_prefix = o->bucket_prefix;
552  o->bucket_prefix_cur = malloc(count + 1);
553  sprintf(o->bucket_prefix_cur, "%s%lu", old_prefix, c % 1000);
554  }else{
556  }
557 
558  // init bucket context
559  memset(& o->bucket_context, 0, sizeof(o->bucket_context));
560  o->bucket_context.hostName = o->host;
561  o->bucket_context.bucketName = o->bucket_prefix_cur;
562  if (o->use_ssl){
563  o->s3_protocol = S3ProtocolHTTPS;
564  }else{
565  o->s3_protocol = S3ProtocolHTTP;
566  }
567  o->bucket_context.protocol = o->s3_protocol;
568  o->bucket_context.uriStyle = S3UriStylePath;
569  o->bucket_context.accessKeyId = o->access_key;
570  o->bucket_context.secretAccessKey = o->secret_key;
571 
572  if (! o->bucket_per_file && rank == 0){
573  S3_create_bucket(o->s3_protocol, o->access_key, o->secret_key, NULL, o->host, o->bucket_context.bucketName, o->authRegion, S3CannedAclPrivate, o->locationConstraint, NULL, o->timeout, & responseHandler, NULL);
574  CHECK_ERROR(o->bucket_context.bucketName);
575  }
576 
577  if ( ret != S3StatusOK ){
578  FAIL("S3 error %s", S3_get_status_name(ret));
579  }
580 }
581 
583  s3_options_t * o = (s3_options_t*) options;
584  if (! o->bucket_per_file && rank == 0){
585  S3_delete_bucket(o->s3_protocol, S3UriStylePath, o->access_key, o->secret_key, NULL, o->host, o->bucket_context.bucketName, o->authRegion, NULL, o->timeout, & responseHandler, NULL);
586  CHECK_ERROR(o->bucket_context.bucketName);
587  }
588 
589  S3_deinitialize();
590 }
591 
592 
594  .name = "S3-libs3",
595  .name_legacy = NULL,
596  .create = S3_Create,
597  .open = S3_Open,
598  .xfer = S3_Xfer,
599  .close = S3_Close,
600  .delete = S3_Delete,
601  .get_version = S3_getVersion,
602  .fsync = S3_Fsync,
603  .xfer_hints = s3_xfer_hints,
604  .get_file_size = S3_GetFileSize,
605  .statfs = S3_statfs,
606  .mkdir = S3_mkdir,
607  .rmdir = S3_rmdir,
608  .access = S3_access,
609  .stat = S3_stat,
610  .initialize = S3_init,
611  .finalize = S3_final,
612  .get_options = S3_options,
613  .check_params = S3_check_params,
614  .sync = S3_Sync,
615  .enable_mdtest = true
616 };
char * access_key
uint64_t f_blocks
Definition: aiori.h:53
static S3MultipartInitialHandler multipart_handler
static int putObjectDataCallback(int bufferSize, char *buffer, void *callbackData)
static IOR_offset_t S3_Xfer(int access, aiori_fd_t *afd, IOR_size_t *buffer, IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t *options)
uint64_t f_bfree
Definition: aiori.h:54
#define LAST_OPTION
Definition: option.h:39
char const * nextMarker
static S3Status s3status
static void S3_Close(aiori_fd_t *afd, aiori_mod_opt_t *options)
IOR_size_t * buf
S3Status list_delete_cb(int isTruncated, const char *nextMarker, int contentsCount, const S3ListBucketContent *contents, int commonPrefixesCount, const char **commonPrefixes, void *callbackData)
struct benchmark_options o
Definition: md-workbench.c:133
static S3ErrorDetails s3error
S3BucketContext bucket_context
static aiori_xfer_hint_t * hints
static int S3_check_params(aiori_mod_opt_t *options)
static S3Status statResponsePropertiesCallback(const S3ResponseProperties *properties, void *callbackData)
static S3GetObjectHandler getObjectHandler
static void S3_Fsync(aiori_fd_t *fd, aiori_mod_opt_t *options)
static aiori_fd_t * S3_Open(char *path, int flags, aiori_mod_opt_t *options)
static char * S3_getVersion()
uint64_t f_ffree
Definition: aiori.h:57
static aiori_fd_t * S3_Create(char *path, int iorflags, aiori_mod_opt_t *options)
static void def_file_name(s3_options_t *o, char *out_name, char const *path)
#define FAIL(...)
Definition: aiori-debug.h:16
static void S3_Sync(aiori_mod_opt_t *options)
#define WRITE
Definition: iordef.h:100
char * locationConstraint
char * bucket_prefix
static S3Status S3ListResponseCallback(const char *ownerId, const char *ownerDisplayName, const char *bucketName, int64_t creationDateSeconds, void *callbackData)
static S3Status responsePropertiesCallback(const S3ResponseProperties *properties, void *callbackData)
#define IOR_CREAT
Definition: aiori.h:32
static void def_bucket_name(s3_options_t *o, char *out_name, char const *path)
static S3ListServiceHandler listhandler
uint64_t f_files
Definition: aiori.h:56
static option_help options[]
Definition: aiori-CEPHFS.c:59
static option_help * S3_options(aiori_mod_opt_t **init_backend_options, aiori_mod_opt_t *init_values)
#define CHECK_ERROR(p)
uint64_t f_bsize
Definition: aiori.h:52
static S3ListBucketHandler list_delete_handler
static void S3_final(aiori_mod_opt_t *options)
static S3ResponseHandler statResponseHandler
char * bucket_prefix_cur
#define WARN(MSG)
Definition: aiori-debug.h:45
static S3Status S3multipart_handler(const char *upload_id, void *callbackData)
S3Protocol s3_protocol
static int S3_stat(const char *path, struct stat *buf, aiori_mod_opt_t *options)
static IOR_offset_t S3_GetFileSize(aiori_mod_opt_t *options, char *testFileName)
char * secret_key
static S3Status getObjectDataCallback(int bufferSize, const char *buffer, void *callbackData)
char * object
static int S3_mkdir(const char *path, mode_t mode, aiori_mod_opt_t *options)
#define IOR_WRONLY
Definition: aiori.h:29
long long int IOR_size_t
Definition: iordef.h:124
static void S3_Delete(char *path, aiori_mod_opt_t *options)
uint64_t f_bavail
Definition: aiori.h:55
static int S3_rmdir(const char *path, aiori_mod_opt_t *options)
static S3PutObjectHandler putObjectHandler
static void S3_init(aiori_mod_opt_t *options)
static void responseCompleteCallback(S3Status status, const S3ErrorDetails *error, void *callbackData)
char * authRegion
#define IOR_RDWR
Definition: aiori.h:30
static void s3_xfer_hints(aiori_xfer_hint_t *params)
char * name
Definition: aiori.h:88
static int S3_access(const char *path, int mode, aiori_mod_opt_t *options)
long long int IOR_offset_t
Definition: iordef.h:123
int rank
Definition: utilities.c:70
ior_aiori_t S3_libS3_aiori
s3_options_t * o
static int S3_statfs(const char *path, ior_aiori_statfs_t *stat, aiori_mod_opt_t *options)
static S3ResponseHandler responseHandler
#define NULL
Definition: iordef.h:84