root/ompi/mca/io/romio321/romio/adio/common/ad_fstype.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIO_FileSysType_parentdir
  2. ADIO_FileSysType_fncall
  3. ADIO_FileSysType_fncall_scalable
  4. ADIO_FileSysType_prefix
  5. ADIO_ResolveFileType

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /* 
   3  *   Copyright (C) 1997 University of Chicago. 
   4  *   See COPYRIGHT notice in top-level directory.
   5  */
   6 
   7 /* This file is quickly becoming the single one, outside the ADIO
   8  * implementations, which has "what ADIO components are built in" code in it.
   9  */
  10 
  11 #include "adio.h"
  12 
  13 #ifdef HAVE_UNISTD_H
  14 #include <unistd.h>
  15 #endif
  16 
  17 #ifdef HAVE_SYS_PARAM_H
  18 #include <sys/param.h>
  19 #endif
  20 
  21 #ifdef HAVE_PVFS_H
  22 #include "pvfs.h"
  23 #endif
  24 
  25 #ifdef HAVE_PVFS2_H
  26 #include "pvfs2.h"
  27 #endif
  28 
  29 #ifdef HAVE_ZOIDFS_H
  30 #include "zoidfs.h"
  31 #endif
  32 
  33 #ifdef HAVE_GPFS_H
  34 #include "gpfs.h"
  35 #endif
  36 
  37 /* Notes on detection process:
  38  *
  39  * There are three more "general" mechanisms that we use for detecting
  40  * file system type:
  41  * - struct statfs's f_type field
  42  * - struct statvfs's f_basetype field
  43  * - struct stat's st_fstype field
  44  *
  45  * Otherwise we'll fall back on some OS-specific approach.
  46  */
  47 
  48 #ifdef HAVE_STRUCT_STATFS
  49 # ifdef HAVE_SYS_VFS_H
  50 # include <sys/vfs.h>
  51 # endif
  52 # ifdef HAVE_SYS_STATVFS_H
  53 # include <sys/statvfs.h>
  54 # endif
  55 # ifdef HAVE_SYS_PARAM_H
  56 # include <sys/param.h>
  57 # endif
  58 # ifdef HAVE_SYS_MOUNT_H
  59 # include <sys/mount.h>
  60 # endif
  61  /* On Linux platforms, linux/nfs_fs.h is all messed up and cannot be
  62   * reliably included.
  63   */
  64 # if defined(ROMIO_NFS) && !defined(NFS_SUPER_MAGIC)
  65 # define NFS_SUPER_MAGIC 0x6969
  66 # endif
  67 
  68 # if defined(ROMIO_PANFS) && !defined(PAN_KERNEL_FS_CLIENT_SUPER_MAGIC)
  69 # define PAN_KERNEL_FS_CLIENT_SUPER_MAGIC 0xAAD7AAEA
  70 # endif
  71 #endif
  72 
  73 # if defined(ROMIO_XFS) && !defined(XFS_SUPER_MAGIC)
  74 # define XFS_SUPER_MAGIC 0x58465342
  75 # endif
  76 
  77 #if !defined(PVFS2_SUPER_MAGIC)
  78 #define PVFS2_SUPER_MAGIC (0x20030528)
  79 #endif
  80 
  81 #if defined(ROMIO_GPFS) && !defined(GPFS_SUPER_MAGIC)
  82 # define GPFS_SUPER_MAGIC 0x47504653
  83 #endif
  84 
  85 #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
  86 # ifdef HAVE_SYS_STATVFS_H
  87 # include <sys/statvfs.h>
  88 # endif
  89 # ifdef HAVE_SYS_VFS_H
  90 # include <sys/vfs.h>
  91 # endif
  92 # ifdef HAVE_SYS_PARAM_H
  93 # include <sys/param.h>
  94 # endif
  95 # ifdef HAVE_SYS_MOUNT_H
  96 # include <sys/mount.h>
  97 # endif
  98 #endif
  99 
 100 #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
 101 # ifdef HAVE_SYS_TYPES_H
 102 # include <sys/types.h>
 103 # endif
 104 # ifdef HAVE_SYS_STAT_H
 105 # include <sys/stat.h>
 106 # endif
 107 #endif
 108 
 109 /* ADIO_FileSysType_parentdir is only used if one of these is defined.
 110    By including this test, we avoid warnings about unused static functions
 111    from the compiler */
 112 #if defined(ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || \
 113     defined(HAVE_STRUCT_STATFS) || \
 114     defined(ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) 
 115 #ifndef ROMIO_NTFS
 116 #define ROMIO_NEEDS_ADIOPARENTDIR
 117 static void ADIO_FileSysType_parentdir(const char *filename, char **dirnamep);
 118 #endif
 119 #endif 
 120 static void ADIO_FileSysType_prefix(const char *filename, int *fstype,
 121                                     int *error_code);
 122 static void ADIO_FileSysType_fncall(const char *filename, int *fstype,
 123                                     int *error_code);
 124 
 125 /*
 126  ADIO_FileSysType_parentdir - determines a string pathname for the
 127  parent directory of a given filename.
 128 
 129 Input Parameters:
 130 . filename - pointer to file name character array
 131 
 132 Output Parameters:
 133 . dirnamep - pointer to location in which to store a pointer to a string
 134 
 135  Note that the caller should free the memory located at the pointer returned
 136  after the string is no longer needed.
 137 */
 138 #ifdef ROMIO_NEEDS_ADIOPARENTDIR
 139 
 140 /* In a strict ANSI environment, S_ISLNK may not be defined.  Fix that
 141    here.  We assume that S_ISLNK is *always* defined as a macro.  If
 142    that is not universally true, then add a test to the romio
 143    configure that trys to link a program that references S_ISLNK */
 144 #if !defined(S_ISLNK) 
 145 #    if defined(S_IFLNK)
 146      /* Check for the link bit */
 147 #    define S_ISLNK(mode) ((mode) & S_IFLNK)
 148 #    else
 149      /* no way to check if it is a link, so say false */
 150 #    define S_ISLNK(mode) 0   
 151 #    endif
 152 #endif /* !(S_ISLNK) */
 153 
 154 /* ADIO_FileSysType_parentdir
 155  *
 156  * Returns pointer to string in dirnamep; that string is allocated with
 157  * strdup and must be free()'d.
 158  */
 159 static void ADIO_FileSysType_parentdir(const char *filename, char **dirnamep)
 160 {
 161     int err;
 162     char *dir = NULL, *slash;
 163     struct stat statbuf;
 164     
 165     err = lstat(filename, &statbuf);
 166 
 167     if (err || (!S_ISLNK(statbuf.st_mode))) {
 168         /* no such file, or file is not a link; these are the "normal"
 169          * cases where we can just return the parent directory.
 170          */
 171         dir = ADIOI_Strdup(filename);
 172     }
 173     else {
 174         /* filename is a symlink.  we've presumably already tried
 175          * to stat it and found it to be missing (dangling link),
 176          * but this code doesn't care if the target is really there
 177          * or not.
 178          */
 179         ssize_t namelen;
 180         char *linkbuf;
 181 
 182         linkbuf = ADIOI_Malloc(PATH_MAX+1);
 183         namelen = readlink(filename, linkbuf, PATH_MAX+1);
 184         if (namelen == -1) {
 185             /* something strange has happened between the time that
 186              * we determined that this was a link and the time that
 187              * we attempted to read it; punt and use the old name.
 188              */
 189             dir = ADIOI_Strdup(filename);
 190         }
 191         else {
 192             /* successfully read the link */
 193             linkbuf[namelen] = '\0'; /* readlink doesn't null terminate */
 194             dir = ADIOI_Strdup(linkbuf);
 195         }
 196         ADIOI_Free(linkbuf);
 197     }
 198 
 199     slash = strrchr(dir, '/');
 200     if (!slash) ADIOI_Strncpy(dir, ".", 2);
 201     else {
 202         if (slash == dir) *(dir + 1) = '\0';
 203         else *slash = '\0';
 204     }
 205 
 206     *dirnamep = dir;
 207     return;
 208 }
 209 #endif /* ROMIO_NTFS */
 210 
 211 /*
 212  ADIO_FileSysType_fncall - determines the file system type for a given file
 213  using a system-dependent function call
 214 
 215 Input Parameters:
 216 . filename - pointer to file name character array
 217 
 218 Output Parameters:
 219 . fstype - location in which to store file system type (ADIO_XXX)
 220 . error_code - location in which to store error code
 221 
 222  MPI_SUCCESS is stored in the location pointed to by error_code on success.
 223 
 224  This function is used by MPI_File_open() and MPI_File_delete() to determine 
 225  file system type.  Most other functions use the type which is stored when the 
 226  file is opened.
 227  */
 228 static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code)
 229 {
 230 #if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE)
 231     int err;
 232 #endif
 233 
 234 #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
 235     struct statvfs vfsbuf;
 236 #endif
 237 #ifdef HAVE_STRUCT_STATFS
 238     struct statfs fsbuf;
 239 #endif
 240 #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
 241     struct stat sbuf;
 242 #endif
 243     static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL";
 244 
 245 /* NFS can get stuck and end up returing ESTALE "forever" */
 246 #define MAX_ESTALE_RETRY 10000
 247     int retry_cnt;
 248 
 249     *error_code = MPI_SUCCESS;
 250 
 251 #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
 252     /* rare: old solaris machines */
 253     retry_cnt=0;
 254     do {
 255         err = statvfs(filename, &vfsbuf);
 256     } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);
 257 
 258     if (err) {
 259         /* ENOENT may be returned in two cases:
 260          * 1) no directory entry for "filename"
 261          * 2) "filename" is a dangling symbolic link
 262          *
 263          * ADIO_FileSysType_parentdir tries to deal with both cases.
 264          */
 265         if (errno == ENOENT) {
 266             char *dir;
 267             ADIO_FileSysType_parentdir(filename, &dir);
 268             err = statvfs(dir, &vfsbuf);
 269 
 270             ADIOI_Free(dir);
 271         }
 272         else {
 273             *error_code = ADIOI_Err_create_code(myname, filename, errno);
 274             if(*error_code != MPI_SUCCESS) return;
 275         }
 276     }
 277 
 278     /* --BEGIN ERROR HANDLING-- */
 279     if (err) {
 280         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 281                                            myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 282                                            "**filename", "**filename %s", filename);
 283         return;
 284     }
 285     /* --END ERROR HANDLING-- */
 286 
 287     /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
 288     if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) {
 289         *fstype = ADIO_NFS;
 290         return;
 291     }
 292     if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) {
 293         *fstype = ADIO_XFS;
 294         return;
 295     }
 296 
 297 # ifdef ROMIO_UFS
 298     /* if UFS support is enabled, default to that */
 299     *fstype = ADIO_UFS;
 300     return;
 301 # endif
 302 
 303     /* --BEGIN ERROR HANDLING-- */
 304     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 305                                        myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 306                                        "**filename", "**filename %s", filename);
 307     /* --END ERROR HANDLING-- */
 308 #endif /* STATVFS APPROACH */
 309 
 310 #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS)
 311     /* common automagic fs-detection logic for any modern POSX-compliant
 312      * environment */
 313     retry_cnt = 0;
 314     do {
 315         err = statfs(filename, &fsbuf);
 316     } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);
 317 
 318     if (err) {
 319         if(errno == ENOENT) {
 320             char *dir;
 321             ADIO_FileSysType_parentdir(filename, &dir);
 322             err = statfs(dir, &fsbuf);
 323             ADIOI_Free(dir);
 324         }
 325         else {
 326             *error_code = ADIOI_Err_create_code(myname, filename, errno);
 327             if(*error_code != MPI_SUCCESS) return;
 328         }
 329     }
 330 
 331     /* --BEGIN ERROR HANDLING-- */
 332     if (err) {
 333         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 334                                            myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 335                                            "**filename", "**filename %s", filename);
 336         return;
 337     }
 338     /* --END ERROR HANDLING-- */
 339 
 340 # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME
 341     /* uncommon: maybe only on Darwin ? */
 342     if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) {
 343         *fstype = ADIO_NFS;
 344         return;
 345     }
 346 # endif
 347 
 348 
 349 #ifdef ROMIO_GPFS
 350     if (fsbuf.f_type == GPFS_SUPER_MAGIC) {
 351         *fstype = ADIO_GPFS;
 352         return;
 353     }
 354 #endif
 355 
 356     /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
 357 # ifdef NFS_SUPER_MAGIC
 358     if (fsbuf.f_type == NFS_SUPER_MAGIC) {
 359         *fstype = ADIO_NFS;
 360         return;
 361     }
 362 # endif
 363 
 364 #ifdef ROMIO_LUSTRE
 365 # ifndef LL_SUPER_MAGIC
 366 #  define LL_SUPER_MAGIC 0x0BD00BD0
 367 # endif
 368     if (fsbuf.f_type == LL_SUPER_MAGIC) {
 369         *fstype = ADIO_LUSTRE;
 370         return;
 371     }
 372 #endif
 373 
 374 # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
 375     if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
 376         *fstype = ADIO_PANFS;
 377         return;
 378     }
 379 # endif
 380 
 381 # ifdef MOUNT_NFS
 382     if (fsbuf.f_type == MOUNT_NFS) {
 383         *fstype = ADIO_NFS;
 384         return;
 385     }
 386 # endif
 387 
 388 # ifdef MOUNT_PFS
 389     if (fsbuf.f_type == MOUNT_PFS) {
 390         *fstype = ADIO_PFS;
 391         return;
 392     }
 393 # endif
 394 
 395 # ifdef PVFS_SUPER_MAGIC
 396     if (fsbuf.f_type == PVFS_SUPER_MAGIC) {
 397         *fstype = ADIO_PVFS;
 398         return;
 399     }
 400 # endif
 401 
 402 # ifdef PVFS2_SUPER_MAGIC
 403     if (fsbuf.f_type == PVFS2_SUPER_MAGIC) {
 404         *fstype = ADIO_PVFS2;
 405         return;
 406     }
 407 # endif
 408 
 409 # ifdef XFS_SUPER_MAGIC
 410     if (fsbuf.f_type == XFS_SUPER_MAGIC) {
 411             *fstype = ADIO_XFS;
 412             return;
 413     }
 414 # endif
 415 
 416 # ifdef ROMIO_UFS
 417     /* if UFS support is enabled, default to that */
 418     *fstype = ADIO_UFS;
 419     return;
 420 # endif
 421     /* --BEGIN ERROR HANDLING-- */
 422     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 423                                        myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 424                                        "**filename", "**filename %s", filename);
 425     /* --END ERROR HANDLING-- */
 426 #endif /* STATFS APPROACH */
 427 
 428 #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
 429     /* rare: maybe old NEC SX or SGI IRIX machines */
 430     retry_cnt = 0;
 431     do {
 432         err = stat(filename, &sbuf);
 433     } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);
 434 
 435     if (err) {
 436         if(errno == ENOENT) {
 437             char *dir;
 438             ADIO_FileSysType_parentdir(filename, &dir);
 439             err = stat(dir, &sbuf);
 440             ADIOI_Free(dir);
 441         }
 442         else{
 443             *error_code = ADIOI_Err_create_code(myname, filename, errno);
 444             if(*error_code != MPI_SUCCESS) return;
 445         }
 446     }
 447     
 448     if (err) {
 449         /* --BEGIN ERROR HANDLING-- */
 450         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 451                                            myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 452                                            "**filename", "**filename %s", filename);
 453         /* --END ERROR HANDLING-- */
 454         return;
 455     }
 456     else {
 457         if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
 458         else *fstype = ADIO_SFS; /* assuming SX4 for now */
 459     }
 460 #endif /* STAT APPROACH */
 461 
 462 #ifdef ROMIO_NTFS
 463     ADIOI_UNREFERENCED_ARG(filename);
 464     ADIOI_UNREFERENCED_ARG(error_code);
 465     *fstype = ADIO_NTFS; /* only supported FS on Windows */
 466 #elif defined(ROMIO_NFS)
 467     *fstype = ADIO_NFS;
 468 #elif defined(ROMIO_UFS)
 469     *fstype = ADIO_UFS;
 470 #else
 471     /* --BEGIN ERROR HANDLING-- */
 472     *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 473                                        myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 474                                        "**filename", "**filename %s", filename);
 475     /* --END ERROR HANDLING-- */
 476 #endif
 477 }
 478 
 479 /* all proceeses opening, creating, or deleting a file end up invoking several
 480  * stat system calls (unless a fs prefix is given).  Cary out this file system
 481  * detection in a more scalable way by having rank 0 stat the file and broadcast the result (fs type and error code) to the other mpi processes */
 482 
 483 static void ADIO_FileSysType_fncall_scalable(MPI_Comm comm, const char *filename, int * file_system, int * error_code)
 484 {
 485     int rank;
 486     int buf[2];
 487     MPI_Comm_rank(comm, &rank);
 488 
 489     if (rank == 0) {
 490         ADIO_FileSysType_fncall(filename, file_system, error_code);
 491         buf[0] = *file_system;
 492         buf[1] = *error_code;
 493     }
 494     MPI_Bcast(buf, 2, MPI_INT, 0, comm);
 495     *file_system = buf[0];
 496     *error_code = buf[1];
 497 }
 498 
 499 
 500 
 501 /*
 502   ADIO_FileSysType_prefix - determines file system type for a file using 
 503   a prefix on the file name.  upper layer should have already determined
 504   that a prefix is present.
 505 
 506 Input Parameters:
 507 . filename - path to file, including prefix (xxx:)
 508 
 509 Output Parameters:
 510 . fstype - pointer to integer in which to store file system type (ADIO_XXX)
 511 . error_code - pointer to integer in which to store error code
 512 
 513   Returns MPI_SUCCESS in error_code on success.  Filename not having a prefix
 514   is considered an error. Except for on Windows systems where the default is NTFS.
 515 
 516  */
 517 static void ADIO_FileSysType_prefix(const char *filename, int *fstype, int *error_code)
 518 {
 519     static char myname[] = "ADIO_RESOLVEFILETYPE_PREFIX";
 520     *error_code = MPI_SUCCESS;
 521 
 522     if (!strncmp(filename, "pfs:", 4) || !strncmp(filename, "PFS:", 4)) {
 523         *fstype = ADIO_PFS;
 524     }
 525     else if (!strncmp(filename, "piofs:", 6) || !strncmp(filename, "PIOFS:", 6)) {
 526         *fstype = ADIO_PIOFS;
 527     }
 528     else if (!strncmp(filename, "ufs:", 4) || !strncmp(filename, "UFS:", 4)) {
 529         *fstype = ADIO_UFS;
 530     }
 531     else if (!strncmp(filename, "nfs:", 4) || !strncmp(filename, "NFS:", 4)) {
 532         *fstype = ADIO_NFS;
 533     }
 534     else if (!strncmp(filename, "panfs:", 6) || !strncmp(filename, "PANFS:", 6)) {
 535         *fstype = ADIO_PANFS;
 536     }
 537     else if (!strncmp(filename, "hfs:", 4) || !strncmp(filename, "HFS:", 4)) {
 538         *fstype = ADIO_HFS;
 539     }
 540     else if (!strncmp(filename, "xfs:", 4) || !strncmp(filename, "XFS:", 4)) {
 541         *fstype = ADIO_XFS;
 542     }
 543     else if (!strncmp(filename, "sfs:", 4) || !strncmp(filename, "SFS:", 4)) {
 544         *fstype = ADIO_SFS;
 545     }
 546     else if (!strncmp(filename, "pvfs:", 5) || !strncmp(filename, "PVFS:", 5)) {
 547         *fstype = ADIO_PVFS;
 548     }
 549     else if (!strncmp(filename, "pvfs2:", 6)||!strncmp(filename, "PVFS2:", 6)) {
 550         *fstype = ADIO_PVFS2;
 551     }
 552     else if (!strncmp(filename, "zoidfs:", 7)||
 553                     !strncmp(filename, "ZOIDFS:", 7)) {
 554             *fstype = ADIO_ZOIDFS;
 555     } 
 556     else if (!strncmp(filename, "testfs:", 7) 
 557              || !strncmp(filename, "TESTFS:", 7))
 558     {
 559         *fstype = ADIO_TESTFS;
 560     }
 561     else if (!strncmp(filename, "ftp:", 4) 
 562                     || !strncmp(filename, "gsiftp:", 7))
 563     {
 564         *fstype = ADIO_GRIDFTP;
 565     }
 566     else if (!strncmp(filename, "lustre:", 7) 
 567              || !strncmp(filename, "LUSTRE:", 7))
 568     {
 569         *fstype = ADIO_LUSTRE;
 570     }
 571     else if (!strncmp(filename, "gpfs:", 5) || !strncmp(filename, "GPFS:", 5)) {
 572         *fstype = ADIO_GPFS;
 573     }
 574     else {
 575 #ifdef ROMIO_NTFS
 576         *fstype = ADIO_NTFS;
 577 #else
 578         *fstype = 0;
 579         /* --BEGIN ERROR HANDLING-- */
 580         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 581                                            myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
 582                                            "**filename", "**filename %s", filename);
 583         /* --END ERROR HANDLING-- */
 584 #endif
 585     }
 586 }
 587 
 588 /*@
 589     ADIO_ResolveFileType - determines file system type and operations from
 590                            file name string; this is a collective call
 591 
 592 Input Parameters:
 593 . comm - communicator across which collective open is performed
 594 . filename - name of file (string)
 595 
 596 Output Parameters:
 597 . fstype - (pointer to) int holding file system type
 598 . ops - (address of) pointer to table of valid file operations
 599 . error_code - (pointer to) int holding error code
 600 
 601 Notes:
 602 This code used to be in MPI_File_open(), but it has been moved into here in 
 603 order to clean things up.  The goal is to separate all this "did we compile
 604 for this fs type" code from the MPI layer and also to introduce the ADIOI_Fns
 605 tables in a reasonable way. -- Rob, 06/06/2001
 606 @*/
 607 void ADIO_ResolveFileType(MPI_Comm comm, const char *filename, int *fstype,
 608                           ADIOI_Fns **ops, int *error_code)
 609 {
 610     int myerrcode, file_system, min_code, max_code;
 611     char *tmp;
 612     static char myname[] = "ADIO_RESOLVEFILETYPE";
 613     char * p;
 614 
 615     file_system = -1;
 616     if (filename == NULL) {
 617             *error_code = ADIOI_Err_create_code(myname, filename, ENOENT);
 618             return;
 619     }
 620     tmp = strchr(filename, ':');
 621     if (!tmp) {
 622         int have_nfs_enabled=0;
 623         *error_code = MPI_SUCCESS;
 624         /* no prefix; use system-dependent function call to determine type */
 625         /* Optimization: we can reduce the 'storm of stats' that result from
 626          * thousands of mpi processes determinig file type this way.  Let us
 627          * have just one process stat the file and broadcast the result to
 628          * everyone else.  
 629          * - Note that we will not catch cases like
 630          * http://www.mcs.anl.gov/web-mail-archive/lists/mpich-discuss/2007/08/msg00042.html
 631          * (edit: now http://lists.mcs.anl.gov/pipermail/mpich-discuss/2007-August/002648.html)
 632          *
 633          * where file systems are not mounted or available on other processes,
 634          * but we'll catch those a few functions later in ADIO_Open 
 635          * - Note that if we have NFS enabled, we might have a situation where,
 636          *   for example, /home/user/data.out is UFS on one process but NFS on
 637          *   others, so we won't perform this optimization if NFS is enabled.
 638          * - Another point: error codes and file system types are broadcast to
 639          *   all members of the communicator, so we get to skip the allreduce
 640          *   steps*/
 641 
 642 #ifdef ROMIO_NFS
 643         have_nfs_enabled=1;
 644 #endif
 645         if (!have_nfs_enabled) {
 646             ADIO_FileSysType_fncall_scalable(comm, filename, &file_system, &myerrcode);
 647             if (myerrcode != MPI_SUCCESS) {
 648                 *error_code = myerrcode;
 649                 return;
 650             }
 651         } else {
 652             ADIO_FileSysType_fncall(filename, &file_system, &myerrcode);
 653 
 654             /* the check for file system type will hang if any process got
 655              * an error in ADIO_FileSysType_fncall.  Processes encountering
 656              * an error will return early, before the collective file
 657              * system type check below.  This case could happen if a full
 658              * path exists on one node but not on others, and no prefix
 659              * like ufs: was provided.  see discussion at
 660              * http://www.mcs.anl.gov/web-mail-archive/lists/mpich-discuss/2007/08/msg00042.html
 661              * (edit: now
 662              * http://lists.mcs.anl.gov/pipermail/mpich-discuss/2007-August/002648.html)
 663              */
 664 
 665             MPI_Allreduce(&myerrcode, &max_code, 1, MPI_INT, MPI_MAX, comm);
 666             if (max_code != MPI_SUCCESS)  {
 667                 *error_code = max_code;
 668                 return;
 669             }
 670             /* ensure everyone came up with the same file system type */
 671             MPI_Allreduce(&file_system, &min_code, 1, MPI_INT,
 672                     MPI_MIN, comm);
 673             if (min_code == ADIO_NFS) file_system = ADIO_NFS;
 674         }
 675     }
 676     else {
 677         /* prefix specified; just match via prefix and assume everyone got 
 678          * the same thing.
 679          *
 680          * perhaps we should have this code go through the allreduce as well?
 681          */
 682         ADIO_FileSysType_prefix(filename, &file_system, &myerrcode);
 683         if (myerrcode != MPI_SUCCESS) {
 684             *error_code = myerrcode;
 685             return;
 686         }
 687     }
 688 
 689     /* lastly, there may be situations where one cannot override the file
 690      * system detection with a prefix -- maybe the file name is passed to both
 691      * posix and MPI-IO routines, or maybe the file name is hard-coded into an
 692      * application.
 693      * Assumes all processes set the same environment varialble.
 694      * Values: the same prefix you would stick on a file path. e.g. pvfs2: --
 695      * including the colon! */
 696     p = getenv("ROMIO_FSTYPE_FORCE");
 697     if (p != NULL) {
 698         ADIO_FileSysType_prefix(p, &file_system, &myerrcode);
 699         if (myerrcode != MPI_SUCCESS) {
 700             *error_code = myerrcode;
 701             return;
 702         }
 703     }
 704 
 705     /* verify that we support this file system type and set ops pointer */
 706     if (file_system == ADIO_PFS) {
 707 #ifndef ROMIO_PFS
 708         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 709                                            myname, __LINE__, MPI_ERR_IO,
 710                                            "**iofstypeunsupported", 0);
 711         return;
 712 #else
 713         *ops = &ADIO_PFS_operations;
 714 #endif
 715     }
 716     if (file_system == ADIO_PIOFS) {
 717 #ifndef ROMIO_PIOFS
 718         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 719                                            myname, __LINE__, MPI_ERR_IO,
 720                                            "**iofstypeunsupported", 0);
 721         return;
 722 #else
 723         *ops = &ADIO_PIOFS_operations;
 724 #endif
 725     }
 726     if (file_system == ADIO_UFS) {
 727 #ifndef ROMIO_UFS
 728         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 729                                            myname, __LINE__, MPI_ERR_IO,
 730                                            "**iofstypeunsupported", 0);
 731         return;
 732 #else
 733         *ops = &ADIO_UFS_operations;
 734 #endif
 735     }
 736     if (file_system == ADIO_NFS) {
 737 #ifndef ROMIO_NFS
 738         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 739                                            myname, __LINE__, MPI_ERR_IO,
 740                                            "**iofstypeunsupported", 0);
 741         return;
 742 #else
 743         *ops = &ADIO_NFS_operations;
 744 #endif
 745     }
 746     if (file_system == ADIO_PANFS) {
 747 #ifndef ROMIO_PANFS
 748         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 749                                            myname, __LINE__, MPI_ERR_IO,
 750                                            "**iofstypeunsupported", 0);
 751         return;
 752 #else
 753         *ops = &ADIO_PANFS_operations;
 754 #endif
 755     }
 756     if (file_system == ADIO_HFS) {
 757 #ifndef ROMIO_HFS
 758         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 759                                            myname, __LINE__, MPI_ERR_IO,
 760                                            "**iofstypeunsupported", 0);
 761         return;
 762 #else
 763         *ops = &ADIO_HFS_operations;
 764 #endif
 765     }
 766     if (file_system == ADIO_XFS) {
 767 #ifndef ROMIO_XFS
 768         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 769                                            myname, __LINE__, MPI_ERR_IO,
 770                                            "**iofstypeunsupported", 0);
 771         return;
 772 #else
 773         *ops = &ADIO_XFS_operations;
 774 #endif
 775     }
 776     if (file_system == ADIO_SFS) {
 777 #ifndef ROMIO_SFS
 778         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 779                                            myname, __LINE__, MPI_ERR_IO,
 780                                            "**iofstypeunsupported", 0);
 781         return;
 782 #else
 783         *ops = &ADIO_SFS_operations;
 784 #endif
 785     }
 786     if (file_system == ADIO_PVFS) {
 787 #ifndef ROMIO_PVFS
 788         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 789                                            myname, __LINE__, MPI_ERR_IO,
 790                                            "**iofstypeunsupported", 0);
 791         return;
 792 #else
 793         *ops = &ADIO_PVFS_operations;
 794 #endif
 795     }
 796     if (file_system == ADIO_PVFS2) {
 797 #ifndef ROMIO_PVFS2
 798         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 799                                            myname, __LINE__, MPI_ERR_IO,
 800                                            "**iofstypeunsupported", 0);
 801         return;
 802 #else
 803         *ops = &ADIO_PVFS2_operations;
 804 #endif
 805     }
 806     if (file_system == ADIO_NTFS) {
 807 #ifndef ROMIO_NTFS
 808         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 809                                            myname, __LINE__, MPI_ERR_IO,
 810                                            "**iofstypeunsupported", 0);
 811         return;
 812 #else
 813         *ops = &ADIO_NTFS_operations;
 814 #endif
 815     }
 816     if (file_system == ADIO_TESTFS) {
 817 #ifndef ROMIO_TESTFS
 818         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 819                                            myname, __LINE__, MPI_ERR_IO,
 820                                            "**iofstypeunsupported", 0);
 821         return;
 822 #else
 823         *ops = &ADIO_TESTFS_operations;
 824 #endif
 825     }
 826 
 827     if (file_system == ADIO_GPFS) {
 828 #ifndef ROMIO_GPFS
 829         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 830                                         myname, __LINE__, MPI_ERR_IO,
 831                                         "**iofstypeunsupported", 0);
 832         return;
 833 #else
 834         *ops = &ADIO_GPFS_operations;
 835 #endif
 836     }
 837 
 838     if (file_system == ADIO_GRIDFTP) {
 839 #ifndef ROMIO_GRIDFTP
 840         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 841                                            myname, __LINE__, MPI_ERR_IO,
 842                                            "**iofstypeunsupported", 0);
 843         return;
 844 #else
 845         *ops = &ADIO_GRIDFTP_operations;
 846 #endif
 847     }
 848     if (file_system == ADIO_LUSTRE) {
 849 #ifndef ROMIO_LUSTRE 
 850         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iofstypeunsupported", 0);
 851         return;
 852 #else
 853         *ops = &ADIO_LUSTRE_operations;
 854 #endif
 855     }
 856     if (file_system == ADIO_ZOIDFS) {
 857 #ifndef ROMIO_ZOIDFS
 858         *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
 859                                            myname, __LINE__, MPI_ERR_IO,
 860                                            "**iofstypeunsupported", 0);
 861         return;
 862 #else
 863         *ops = &ADIO_ZOIDFS_operations;
 864 #endif
 865     }
 866     *error_code = MPI_SUCCESS;
 867     *fstype = file_system;
 868     return;
 869 }
 870 /* 
 871  * vim: ts=8 sts=4 sw=4 noexpandtab 
 872  */

/* [<][>][^][v][top][bottom][index][help] */