IOR
aiori-HDFS.c
Go to the documentation of this file.
1 /* -*- mode: c; indent-tabs-mode: t; -*-
2  * vim:noexpandtab:
3  *
4  * Editing with tabs allows different users to pick their own indentation
5  * appearance without changing the file.
6  */
7 
8 /*
9  * Copyright (c) 2009, Los Alamos National Security, LLC All rights reserved.
10  * Copyright 2009. Los Alamos National Security, LLC. This software was produced
11  * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National
12  * Laboratory (LANL), which is operated by Los Alamos National Security, LLC for
13  * the U.S. Department of Energy. The U.S. Government has rights to use,
14  * reproduce, and distribute this software. NEITHER THE GOVERNMENT NOR LOS
15  * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
16  * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is
17  * modified to produce derivative works, such modified software should be
18  * clearly marked, so as not to confuse it with the version available from
19  * LANL.
20  *
21  * Additionally, redistribution and use in source and binary forms, with or
22  * without modification, are permitted provided that the following conditions are
23  * met:
24  *
25  * • Redistributions of source code must retain the above copyright notice,
26  * this list of conditions and the following disclaimer.
27  *
28  * • Redistributions in binary form must reproduce the above copyright notice,
29  * this list of conditions and the following disclaimer in the documentation
30  * and/or other materials provided with the distribution.
31  *
32  * • Neither the name of Los Alamos National Security, LLC, Los Alamos National
33  * Laboratory, LANL, the U.S. Government, nor the names of its contributors may be
34  * used to endorse or promote products derived from this software without specific
35  * prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS
38  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
39  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40  * ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
43  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
46  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
47  * OF SUCH DAMAGE.
48  */
49 
50 /******************************************************************************\
51 *
52 * Implement of abstract I/O interface for HDFS.
53 *
54 * HDFS has the added concept of a "File System Handle" which has to be
55 * connected before files are opened. We store this in the IOR_param_t
56 * object that is always passed to our functions. The thing that callers
57 * think of as the "fd" is an hdfsFile, (a pointer).
58 *
59 \******************************************************************************/
60 
61 #ifdef HAVE_CONFIG_H
62 # include "config.h"
63 #endif
64 
65 #include <stdio.h>
66 #include <stdlib.h>
67 
68 #ifdef __linux__
69 # include <sys/ioctl.h> /* necessary for: */
70 # define __USE_GNU /* O_DIRECT and */
71 # include <fcntl.h> /* IO operations */
72 # undef __USE_GNU
73 #endif /* __linux__ */
74 
75 #include <errno.h>
76 #include <fcntl.h> /* IO operations */
77 #include <sys/stat.h>
78 #include <assert.h>
79 /*
80 #ifdef HAVE_LUSTRE_USER
81 # ifdef HAVE_LINUX_LUSTRE_LUSTRE_USER_H
82 # include <linux/lustre/lustre_user.h>
83 # elif defined(HAVE_LUSTRE_LUSTRE_USER_H)
84 # include <lustre/lustre_user.h>
85 # endif
86 #endif
87 */
88 #include "ior.h"
89 #include "aiori.h"
90 #include "utilities.h"
91 
92 #ifndef open64 /* necessary for TRU64 -- */
93 # define open64 open /* unlikely, but may pose */
94 #endif /* not open64 */ /* conflicting prototypes */
95 
96 #ifndef lseek64 /* necessary for TRU64 -- */
97 # define lseek64 lseek /* unlikely, but may pose */
98 #endif /* not lseek64 */ /* conflicting prototypes */
99 
100 #ifndef O_BINARY /* Required on Windows */
101 # define O_BINARY 0
102 #endif
103 
104 #include "hdfs.h"
105 
106 /**************************** P R O T O T Y P E S *****************************/
107 static aiori_fd_t *HDFS_Create(char *testFileName, int flags, aiori_mod_opt_t * param);
108 static aiori_fd_t *HDFS_Open(char *testFileName, int flags, aiori_mod_opt_t * param);
109 static IOR_offset_t HDFS_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
110  IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t * param);
111 static void HDFS_Close(aiori_fd_t *, aiori_mod_opt_t *);
112 static void HDFS_Delete(char *testFileName, aiori_mod_opt_t * param);
113 static void HDFS_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
115 static void hdfs_xfer_hints(aiori_xfer_hint_t * params);
116 static option_help * HDFS_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values);
117 static int HDFS_mkdir (const char *path, mode_t mode, aiori_mod_opt_t * options);
118 static int HDFS_rmdir (const char *path, aiori_mod_opt_t * options);
119 static int HDFS_access (const char *path, int mode, aiori_mod_opt_t * options);
120 static int HDFS_stat (const char *path, struct stat *buf, aiori_mod_opt_t * options);
121 static int HDFS_statfs (const char * path, ior_aiori_statfs_t * stat, aiori_mod_opt_t * options);
122 
124 
125 /************************** D E C L A R A T I O N S ***************************/
126 
128  .name = "HDFS",
129  .name_legacy = NULL,
130  .create = HDFS_Create,
131  .open = HDFS_Open,
132  .xfer = HDFS_Xfer,
133  .close = HDFS_Close,
134  .delete = HDFS_Delete,
135  .get_options = HDFS_options,
136  .get_version = aiori_get_version,
137  .xfer_hints = hdfs_xfer_hints,
138  .fsync = HDFS_Fsync,
139  .get_file_size = HDFS_GetFileSize,
140  .statfs = HDFS_statfs,
141  .mkdir = HDFS_mkdir,
142  .rmdir = HDFS_rmdir,
143  .access = HDFS_access,
144  .stat = HDFS_stat,
145  .enable_mdtest = true
146 };
147 
148 /***************************** F U N C T I O N S ******************************/
149 
151  hints = params;
152 }
153 
154 /************************** O P T I O N S *****************************/
155 typedef struct {
156  char * user;
157  char * name_node;
158  int replicas; /* n block replicas. (0 gets default) */
160  IOR_offset_t block_size; /* internal blk-size. (0 gets default) */
161  // runtime options
162  hdfsFS fs; /* file-system handle */
163  tPort name_node_port; /* (uint16_t) */
165 
166 static void hdfs_connect( hdfs_options_t* o );
167 
168 option_help * HDFS_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){
169  hdfs_options_t * o = malloc(sizeof(hdfs_options_t));
170 
171  if (init_values != NULL){
172  memcpy(o, init_values, sizeof(hdfs_options_t));
173  }else{
174  memset(o, 0, sizeof(hdfs_options_t));
175  char *hdfs_user;
176  hdfs_user = getenv("USER");
177  if (!hdfs_user){
178  hdfs_user = "";
179  }
180  o->user = strdup(hdfs_user);
181  o->name_node = "default";
182  }
183 
184  *init_backend_options = (aiori_mod_opt_t*) o;
185 
186  option_help h [] = {
187  {0, "hdfs.odirect", "Direct I/O Mode", OPTION_FLAG, 'd', & o->direct_io},
188  {0, "hdfs.user", "Username", OPTION_OPTIONAL_ARGUMENT, 's', & o->user},
189  {0, "hdfs.name_node", "Namenode", OPTION_OPTIONAL_ARGUMENT, 's', & o->name_node},
190  {0, "hdfs.replicas", "Number of replicas", OPTION_OPTIONAL_ARGUMENT, 'd', & o->replicas},
191  {0, "hdfs.block_size", "Blocksize", OPTION_OPTIONAL_ARGUMENT, 'l', & o->block_size},
193  };
194  option_help * help = malloc(sizeof(h));
195  memcpy(help, h, sizeof(h));
196  return help;
197 }
198 
199 
200 int HDFS_mkdir (const char *path, mode_t mode, aiori_mod_opt_t * options){
201  hdfs_options_t * o = (hdfs_options_t*) options;
202  hdfs_connect(o);
203  return hdfsCreateDirectory(o->fs, path);
204 }
205 
206 int HDFS_rmdir (const char *path, aiori_mod_opt_t * options){
207  hdfs_options_t * o = (hdfs_options_t*) options;
208  hdfs_connect(o);
209  return hdfsDelete(o->fs, path, 1);
210 }
211 
212 int HDFS_access (const char *path, int mode, aiori_mod_opt_t * options){
213  hdfs_options_t * o = (hdfs_options_t*) options;
214  hdfs_connect(o);
215  return hdfsExists(o->fs, path);
216 }
217 
218 int HDFS_stat (const char *path, struct stat *buf, aiori_mod_opt_t * options){
219  hdfsFileInfo * stat;
220  hdfs_options_t * o = (hdfs_options_t*) options;
221  hdfs_connect(o);
222  stat = hdfsGetPathInfo(o->fs, path);
223  if(stat == NULL){
224  return 1;
225  }
226  memset(buf, 0, sizeof(struct stat));
227  buf->st_atime = stat->mLastAccess;
228  buf->st_size = stat->mSize;
229  buf->st_mtime = stat->mLastMod;
230  buf->st_mode = stat->mPermissions;
231 
232  hdfsFreeFileInfo(stat, 1);
233  return 0;
234 }
235 
236 int HDFS_statfs (const char * path, ior_aiori_statfs_t * stat, aiori_mod_opt_t * options){
237  hdfs_options_t * o = (hdfs_options_t*) options;
238  hdfs_connect(o);
239 
240  stat->f_bsize = hdfsGetDefaultBlockSize(o->fs);
241  stat->f_blocks = hdfsGetCapacity(o->fs) / hdfsGetDefaultBlockSize(o->fs);
242  stat->f_bfree = stat->f_blocks - hdfsGetUsed(o->fs) / hdfsGetDefaultBlockSize(o->fs);
243  stat->f_bavail = 1;
244  stat->f_files = 1;
245  stat->f_ffree = 1;
246  return 0;
247 }
248 
249 /* This is identical to the one in aiori-POSIX.c Doesn't seem like
250  * it would be appropriate in utilities.c.
251  */
252 
254 {
255 /* note that TRU64 needs O_DIRECTIO, SunOS uses directio(),
256  and everyone else needs O_DIRECT */
257 #ifndef O_DIRECT
258 # ifndef O_DIRECTIO
259  WARN("cannot use O_DIRECT");
260 # define O_DIRECT 000000
261 # else /* O_DIRECTIO */
262 # define O_DIRECT O_DIRECTIO
263 # endif /* not O_DIRECTIO */
264 #endif /* not O_DIRECT */
265 
266  *fd |= O_DIRECT;
267 }
268 
269 
270 /*
271  * "Connect" to an HDFS file-system. HDFS requires this be done before and
272  * files are opened. It is easy for ior_aiori.open/create to assure that
273  * we connect, if we haven't already done so. However, there's not a
274  * simple way to assure that we disconnect after the last file-close. For
275  * now, we'll make a special call at the end of ior.c
276  *
277  * NOTE: It's okay to call this thing whenever you need to be sure the HDFS
278  * filesystem is connected.
279  */
281  if (verbose >= VERBOSE_4) {
282  printf("-> hdfs_connect [nn:\"%s\", port:%d, user:%s]\n",
283  o->name_node,
284  o->name_node_port,
285  o->user );
286  }
287 
288  if ( o->fs ) {
289  if (verbose >= VERBOSE_4) {
290  printf("<- hdfs_connect [nothing to do]\n"); /* DEBUGGING */
291  }
292  return;
293  }
294 
295  /* initialize a builder, holding parameters for hdfsBuilderConnect() */
296  struct hdfsBuilder* builder = hdfsNewBuilder();
297  if ( ! builder ){
298  ERR("couldn't create an hdfsBuilder");
299  }
300 
301  hdfsBuilderSetForceNewInstance ( builder ); /* don't use cached instance */
302 
303  hdfsBuilderSetNameNode ( builder, o->name_node );
304  hdfsBuilderSetNameNodePort( builder, o->name_node_port );
305  hdfsBuilderSetUserName ( builder, o->user );
306 
307  /* NOTE: hdfsBuilderConnect() frees the builder */
308  o->fs = hdfsBuilderConnect( builder );
309  if ( ! o->fs )
310  ERR("hdsfsBuilderConnect failed");
311 
312  if (verbose >= VERBOSE_4) {
313  printf("<- hdfs_connect [success]\n");
314  }
315 }
316 
318  if (verbose >= VERBOSE_4) {
319  printf("-> hdfs_disconnect\n");
320  }
321  if ( o->fs ) {
322  hdfsDisconnect( o->fs );
323  o->fs = NULL;
324  }
325  if (verbose >= VERBOSE_4) {
326  printf("<- hdfs_disconnect\n");
327  }
328 }
329 
330 
331 /*
332  * Create or open the file. Pass TRUE if creating and FALSE if opening an existing file.
333  * Return an hdfsFile.
334  */
335 
336 static void *HDFS_Create_Or_Open( char *testFileName, int flags, aiori_mod_opt_t *param, unsigned char createFile ) {
337  if (verbose >= VERBOSE_4) {
338  printf("-> HDFS_Create_Or_Open\n");
339  }
340  hdfs_options_t * o = (hdfs_options_t*) param;
341 
342  hdfsFile hdfs_file = NULL;
343  int fd_oflags = 0, hdfs_return;
344 
345  /* initialize file-system handle, if needed */
346  hdfs_connect( o );
347 
348  /*
349  * Check for unsupported flags.
350  *
351  * If they want RDWR, we don't know if they're going to try to do both, so we
352  * can't default to either O_RDONLY or O_WRONLY. Thus, we error and exit.
353  *
354  * The other two, we just note that they are not supported and don't do them.
355  */
356 
357  if ( flags & IOR_RDWR ) {
358  ERR( "Opening or creating a file in RDWR is not implemented in HDFS" );
359  }
360 
361  if ( flags & IOR_EXCL ) {
362  fprintf( stdout, "Opening or creating a file in Exclusive mode is not implemented in HDFS\n" );
363  }
364 
365  if ( flags & IOR_APPEND ) {
366  fprintf( stdout, "Opening or creating a file for appending is not implemented in HDFS\n" );
367  }
368 
369  /*
370  * Setup the flags to be used.
371  */
372 
373  if ( createFile == TRUE ) {
374  fd_oflags = O_CREAT;
375  }
376 
377  if ( flags & IOR_WRONLY ) {
378  if ( ! hints->filePerProc ) {
379 
380  // in N-1 mode, only rank 0 truncates the file
381  if ( rank != 0 ) {
382  fd_oflags |= O_WRONLY;
383  } else {
384  fd_oflags |= O_TRUNC;
385  fd_oflags |= O_WRONLY;
386  }
387 
388  } else {
389  // in N-N mode, everyone does truncate
390  fd_oflags |= O_TRUNC;
391  fd_oflags |= O_WRONLY;
392  }
393 
394  } else {
395  fd_oflags |= O_RDONLY;
396  }
397 
398  /*
399  * Now see if O_DIRECT is needed.
400  */
401 
402  if ( o->direct_io == TRUE ) {
403  hdfs_set_o_direct_flag( &fd_oflags );
404  }
405 
406  /*
407  * For N-1 write, All other ranks wait for Rank 0 to open the file.
408  * this is bec 0 does truncate and rest don't
409  * it would be dangerous for all to do truncate as they might
410  * truncate each other's writes
411  */
412 
413  if (( flags & IOR_WRONLY ) && ( ! hints->filePerProc ) && ( rank != 0 )) {
414  MPI_CHECK(MPI_Barrier(testComm), "barrier error");
415  }
416 
417  /*
418  * Now rank zero can open and truncate, if necessary.
419  */
420 
421  if (verbose >= VERBOSE_4) {
422  printf("\thdfsOpenFile(%p, %s, 0%o, %lld, %d, %lld)\n",
423  o->fs,
424  testFileName,
425  fd_oflags, /* shown in octal to compare w/ <bits/fcntl.h> */
426  hints->transferSize,
427  o->replicas,
428  o->block_size);
429  }
430  hdfs_file = hdfsOpenFile( o->fs, testFileName, fd_oflags, hints->transferSize, o->replicas, o->block_size);
431  if ( ! hdfs_file ) {
432  ERR( "Failed to open the file" );
433  }
434 
435  /*
436  * For N-1 write, Rank 0 waits for the other ranks to open the file after it has.
437  */
438 
439  if (( flags & IOR_WRONLY ) &&
440  ( !hints->filePerProc ) &&
441  ( rank == 0 )) {
442 
443  MPI_CHECK(MPI_Barrier(testComm), "barrier error");
444  }
445 
446  if (verbose >= VERBOSE_4) {
447  printf("<- HDFS_Create_Or_Open\n");
448  }
449  return ((void *) hdfs_file );
450 }
451 
452 /*
453  * Create and open a file through the HDFS interface.
454  */
455 
456 static aiori_fd_t *HDFS_Create(char *testFileName, int flags, aiori_mod_opt_t * param) {
457  if (verbose >= VERBOSE_4) {
458  printf("-> HDFS_Create\n");
459  }
460 
461  if (verbose >= VERBOSE_4) {
462  printf("<- HDFS_Create\n");
463  }
464  return HDFS_Create_Or_Open( testFileName, flags, param, TRUE );
465 }
466 
467 /*
468  * Open a file through the HDFS interface.
469  */
470 static aiori_fd_t *HDFS_Open(char *testFileName, int flags, aiori_mod_opt_t * param) {
471  if (verbose >= VERBOSE_4) {
472  printf("-> HDFS_Open\n");
473  }
474 
475  if ( flags & IOR_CREAT ) {
476  if (verbose >= VERBOSE_4) {
477  printf("<- HDFS_Open( ... TRUE)\n");
478  }
479  return HDFS_Create_Or_Open( testFileName, flags, param, TRUE );
480  }
481  else {
482  if (verbose >= VERBOSE_4) {
483  printf("<- HDFS_Open( ... FALSE)\n");
484  }
485  return HDFS_Create_Or_Open( testFileName, flags, param, FALSE );
486  }
487 }
488 
489 /*
490  * Write or read to file using the HDFS interface.
491  */
492 
493 static IOR_offset_t HDFS_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
494  IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t * param) {
495  if (verbose >= VERBOSE_4) {
496  printf("-> HDFS_Xfer(acc:%d, file:%p, buf:%p, len:%llu, %p)\n",
497  access, file, buffer, length, param);
498  }
499  hdfs_options_t * o = (hdfs_options_t*) param;
500  int xferRetries = 0;
501  long long remaining = (long long)length;
502  char* ptr = (char *)buffer;
503  long long rc;
504  hdfsFS hdfs_fs = o->fs; /* (void*) */
505  hdfsFile hdfs_file = (hdfsFile)file; /* (void*) */
506 
507 
508  while ( remaining > 0 ) {
509 
510  /* write/read file */
511  if (access == WRITE) { /* WRITE */
512  if (verbose >= VERBOSE_4) {
513  fprintf( stdout, "task %d writing to offset %lld\n",
514  rank,
515  offset + length - remaining);
516  }
517 
518  if (verbose >= VERBOSE_4) {
519  printf("\thdfsWrite( %p, %p, %p, %lld)\n",
520  hdfs_fs, hdfs_file, ptr, remaining ); /* DEBUGGING */
521  }
522  rc = hdfsWrite( hdfs_fs, hdfs_file, ptr, remaining );
523  if ( rc < 0 ) {
524  ERR( "hdfsWrite() failed" );
525  }
526  offset += rc;
527 
528  if ( hints->fsyncPerWrite == TRUE ) {
529  HDFS_Fsync( file, param );
530  }
531  }
532  else { /* READ or CHECK */
533  if (verbose >= VERBOSE_4) {
534  fprintf( stdout, "task %d reading from offset %lld\n",
535  rank, offset + length - remaining );
536  }
537 
538  if (verbose >= VERBOSE_4) {
539  printf("\thdfsRead( %p, %p, %p, %lld)\n",
540  hdfs_fs, hdfs_file, ptr, remaining ); /* DEBUGGING */
541  }
542  rc = hdfsPread(hdfs_fs, hdfs_file, offset, ptr, remaining);
543  if ( rc == 0 ) {
544  ERR( "hdfs_read() returned EOF prematurely" );
545  }
546 
547  if ( rc < 0 ) {
548  ERR( "hdfs_read() failed" );
549  }
550 
551  offset += rc;
552  }
553 
554 
555  if ( rc < remaining ) {
556  fprintf(stdout, "WARNING: Task %d, partial %s, %lld of %lld bytes at offset %lld\n",
557  rank,
558  access == WRITE ? "hdfsWrite()" : "hdfs_read()",
559  rc, remaining,
560  offset + length - remaining );
561 
562  if ( hints->singleXferAttempt == TRUE ) {
563  MPI_CHECK( MPI_Abort( MPI_COMM_WORLD, -1 ), "barrier error" );
564  }
565 
566  if ( xferRetries > MAX_RETRY ) {
567  ERR( "too many retries -- aborting" );
568  }
569  }
570 
571  assert( rc >= 0 );
572  assert( rc <= remaining );
573  remaining -= rc;
574  ptr += rc;
575  xferRetries++;
576  }
577 
578  if(access == WRITE){
579  // flush user buffer, this makes the write visible to readers
580  // it is the expected semantics of read/writes
581  rc = hdfsHFlush(hdfs_fs, hdfs_file);
582  if(rc != 0){
583  WARN("Error during flush");
584  }
585  }
586 
587  if (verbose >= VERBOSE_4) {
588  printf("<- HDFS_Xfer\n");
589  }
590  return ( length );
591 }
592 
593 /*
594  * Perform hdfs_sync().
595  */
596 static void HDFS_Fsync(aiori_fd_t * fd, aiori_mod_opt_t * param) {
597  hdfs_options_t * o = (hdfs_options_t*) param;
598  hdfsFS hdfs_fs = o->fs; /* (void *) */
599  hdfsFile hdfs_file = (hdfsFile)fd; /* (void *) */
600 
601  if (verbose >= VERBOSE_4) {
602  printf("\thdfsFlush(%p, %p)\n", hdfs_fs, hdfs_file);
603  }
604  if ( hdfsHSync( hdfs_fs, hdfs_file ) != 0 ) {
605  // Hsync is implemented to flush out data with newer Hadoop versions
606  WARN( "hdfsFlush() failed" );
607  }
608 }
609 
610 /*
611  * Close a file through the HDFS interface.
612  */
613 
614 static void HDFS_Close(aiori_fd_t * fd, aiori_mod_opt_t * param) {
615  if (verbose >= VERBOSE_4) {
616  printf("-> HDFS_Close\n");
617  }
618  hdfs_options_t * o = (hdfs_options_t*) param;
619 
620  hdfsFS hdfs_fs = o->fs; /* (void *) */
621  hdfsFile hdfs_file = (hdfsFile)fd; /* (void *) */
622 
623  if ( hdfsCloseFile( hdfs_fs, hdfs_file ) != 0 ) {
624  ERR( "hdfsCloseFile() failed" );
625  }
626 
627  if (verbose >= VERBOSE_4) {
628  printf("<- HDFS_Close\n");
629  }
630 }
631 
632 /*
633  * Delete a file through the HDFS interface.
634  *
635  * NOTE: The signature for ior_aiori.delete doesn't include a parameter to
636  * select recursive deletes. We'll assume that that is never needed.
637  */
638 static void HDFS_Delete( char *testFileName, aiori_mod_opt_t * param ) {
639  if (verbose >= VERBOSE_4) {
640  printf("-> HDFS_Delete\n");
641  }
642 
643  hdfs_options_t * o = (hdfs_options_t*) param;
644  char errmsg[256];
645 
646  /* initialize file-system handle, if needed */
647  hdfs_connect(o);
648 
649  if ( ! o->fs )
650  ERR( "Can't delete a file without an HDFS connection" );
651 
652  if ( hdfsDelete( o->fs, testFileName, 0 ) != 0 ) {
653  sprintf(errmsg, "[RANK %03d]: hdfsDelete() of file \"%s\" failed\n",
654  rank, testFileName);
655 
656  WARN( errmsg );
657  }
658  if (verbose >= VERBOSE_4) {
659  printf("<- HDFS_Delete\n");
660  }
661 }
662 
663 /*
664  * Use hdfsGetPathInfo() to get info about file?
665  * Is there an fstat we can use on hdfs?
666  * Should we just use POSIX fstat?
667  */
668 
670  char * testFileName) {
671  if (verbose >= VERBOSE_4) {
672  printf("-> HDFS_GetFileSize(%s)\n", testFileName);
673  }
674  hdfs_options_t * o = (hdfs_options_t*) param;
675 
676  IOR_offset_t aggFileSizeFromStat;
677  IOR_offset_t tmpMin, tmpMax, tmpSum;
678 
679  /* make sure file-system is connected */
680  hdfs_connect( o );
681 
682  /* file-info struct includes size in bytes */
683  if (verbose >= VERBOSE_4) {
684  printf("\thdfsGetPathInfo(%s) ...", testFileName);
685  fflush(stdout);
686  }
687 
688  hdfsFileInfo* info = hdfsGetPathInfo( o->fs, testFileName );
689  if ( ! info )
690  ERR( "hdfsGetPathInfo() failed" );
691  if (verbose >= VERBOSE_4) {
692  printf("done.\n");fflush(stdout);
693  }
694 
695  aggFileSizeFromStat = info->mSize;
696 
697  if (verbose >= VERBOSE_4) {
698  printf("<- HDFS_GetFileSize [%llu]\n", aggFileSizeFromStat);
699  }
700  return ( aggFileSizeFromStat );
701 }
static void * HDFS_Create_Or_Open(char *testFileName, int flags, aiori_mod_opt_t *param, unsigned char createFile)
Definition: aiori-HDFS.c:336
static int HDFS_access(const char *path, int mode, aiori_mod_opt_t *options)
Definition: aiori-HDFS.c:212
static int HDFS_stat(const char *path, struct stat *buf, aiori_mod_opt_t *options)
Definition: aiori-HDFS.c:218
static aiori_fd_t * HDFS_Create(char *testFileName, int flags, aiori_mod_opt_t *param)
Definition: aiori-HDFS.c:456
uint64_t f_blocks
Definition: aiori.h:53
static int HDFS_rmdir(const char *path, aiori_mod_opt_t *options)
Definition: aiori-HDFS.c:206
static void HDFS_Delete(char *testFileName, aiori_mod_opt_t *param)
Definition: aiori-HDFS.c:638
static void HDFS_Fsync(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-HDFS.c:596
uint64_t f_bfree
Definition: aiori.h:54
uint16_t tPort
Definition: ior.h:28
#define LAST_OPTION
Definition: option.h:39
static aiori_xfer_hint_t * hints
Definition: aiori-HDFS.c:123
CURLcode rc
Definition: aiori-S3-4c.c:111
struct benchmark_options o
Definition: md-workbench.c:133
ior_aiori_t hdfs_aiori
Definition: aiori-HDFS.c:127
uint64_t f_ffree
Definition: aiori.h:57
#define IOR_APPEND
Definition: aiori.h:31
static IOR_offset_t HDFS_Xfer(int access, aiori_fd_t *file, IOR_size_t *buffer, IOR_offset_t length, IOR_offset_t offset, aiori_mod_opt_t *param)
Definition: aiori-HDFS.c:493
#define MPI_CHECK(MPI_STATUS, MSG)
Definition: aiori-debug.h:97
#define WRITE
Definition: iordef.h:100
tPort name_node_port
Definition: aiori-HDFS.c:163
#define IOR_CREAT
Definition: aiori.h:32
#define IOR_EXCL
Definition: aiori.h:34
char * aiori_get_version()
Definition: aiori.c:235
static int HDFS_statfs(const char *path, ior_aiori_statfs_t *stat, aiori_mod_opt_t *options)
Definition: aiori-HDFS.c:236
uint64_t f_files
Definition: aiori.h:56
MPI_Comm testComm
Definition: utilities.c:73
#define O_DIRECT
static option_help options[]
Definition: aiori-CEPHFS.c:59
char * name_node
Definition: aiori-HDFS.c:157
static void hdfs_xfer_hints(aiori_xfer_hint_t *params)
Definition: aiori-HDFS.c:150
uint64_t f_bsize
Definition: aiori.h:52
void * hdfsFS
Definition: ior.h:29
IOR_offset_t block_size
Definition: aiori-HDFS.c:160
#define WARN(MSG)
Definition: aiori-debug.h:45
static int HDFS_mkdir(const char *path, mode_t mode, aiori_mod_opt_t *options)
Definition: aiori-HDFS.c:200
int singleXferAttempt
Definition: aiori.h:75
#define MAX_RETRY
Definition: iordef.h:115
void hdfs_set_o_direct_flag(int *fd)
Definition: aiori-HDFS.c:253
IOR_offset_t transferSize
Definition: aiori.h:73
static option_help * HDFS_options(aiori_mod_opt_t **init_backend_options, aiori_mod_opt_t *init_values)
Definition: aiori-HDFS.c:168
static void hdfs_connect(hdfs_options_t *o)
Definition: aiori-HDFS.c:280
#define IOR_WRONLY
Definition: aiori.h:29
#define FALSE
Definition: iordef.h:76
static void HDFS_Close(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-HDFS.c:614
long long int IOR_size_t
Definition: iordef.h:124
uint64_t f_bavail
Definition: aiori.h:55
static aiori_fd_t * HDFS_Open(char *testFileName, int flags, aiori_mod_opt_t *param)
Definition: aiori-HDFS.c:470
int verbose
Definition: utilities.c:72
#define VERBOSE_4
Definition: iordef.h:110
static void hdfs_disconnect(hdfs_options_t *o)
Definition: aiori-HDFS.c:317
#define ERR(MSG)
Definition: aiori-debug.h:75
#define IOR_RDWR
Definition: aiori.h:30
int fsyncPerWrite
Definition: aiori.h:70
char * name
Definition: aiori.h:88
static IOR_offset_t HDFS_GetFileSize(aiori_mod_opt_t *, char *)
Definition: aiori-HDFS.c:669
int filePerProc
Definition: aiori.h:65
long long int IOR_offset_t
Definition: iordef.h:123
int rank
Definition: utilities.c:70
#define TRUE
Definition: iordef.h:80
#define NULL
Definition: iordef.h:84