/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code) { #if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; /* NFS can get stuck and end up returing ESTALE "forever" */ #define MAX_ESTALE_RETRY 10000 int retry_cnt; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE /* rare: old solaris machines */ retry_cnt=0; do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ if (errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) /* common automagic fs-detection logic for any modern POSX-compliant * environment */ retry_cnt = 0; do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME /* uncommon: maybe only on Darwin ? */ if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_GPFS if (fsbuf.f_type == GPFS_SUPER_MAGIC) { *fstype = ADIO_GPFS; return; } #endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_LUSTRE # ifndef LL_SUPER_MAGIC # define LL_SUPER_MAGIC 0x0BD00BD0 # endif if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } #endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef XFS_SUPER_MAGIC if (fsbuf.f_type == XFS_SUPER_MAGIC) { *fstype = ADIO_XFS; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE /* rare: maybe old NEC SX or SGI IRIX machines */ retry_cnt = 0; do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } else{ *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code) { #ifndef ROMIO_NTFS char *dir; int err; #endif #if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY)) struct statvfs vfsbuf; #endif #if (defined(LINUX) || defined(FREEBSD) || defined(tflops)) struct statfs fsbuf; #endif #ifdef PARAGON struct estatfs ebuf; #endif #ifdef SX4 struct stat sbuf; #endif *error_code = MPI_SUCCESS; #if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY)) do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) *fstype = ADIO_NFS; else { # if (defined(HPUX) || defined(SPPUX)) # ifdef HFS *fstype = ADIO_HFS; # else *fstype = ADIO_UFS; # endif # else if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) *fstype = ADIO_XFS; else if (!strncmp(vfsbuf.f_basetype, "piofs", 4)) *fstype = ADIO_PIOFS; else *fstype = ADIO_UFS; # endif } } #elif defined(LINUX) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ if (fsbuf.f_type == NFS_SUPER_MAGIC) *fstype = ADIO_NFS; # ifdef ROMIO_PVFS else if (fsbuf.f_type == PVFS_SUPER_MAGIC) *fstype = ADIO_PVFS; # endif else *fstype = ADIO_UFS; } #elif (defined(FREEBSD) && defined(HAVE_MOUNT_NFS)) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { # if (__FreeBSD_version>300004) if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) *fstype = ADIO_NFS; # else if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; # endif else *fstype = ADIO_UFS; } #elif defined(PARAGON) do { err = statpfs(filename, &ebuf, 0, 0); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statpfs(dir, &ebuf, 0, 0); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (ebuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; else if (ebuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS; else *fstype = ADIO_UFS; } #elif defined(tflops) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; else if (fsbuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS; else *fstype = ADIO_UFS; } #elif defined(SX4) do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; } #else /* on other systems, make NFS the default */ # ifdef ROMIO_NTFS *fstype = ADIO_NTFS; # else *fstype = ADIO_NFS; # endif *error_code = MPI_SUCCESS; #endif }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code) { #ifndef ROMIO_NTFS char *dir; int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif # ifdef ROMIO_BGL /* BlueGene is a special case: all file systems are AD_BGL, except for * certain exceptions */ *fstype = ADIO_BGL; check_for_lockless_exceptions(fsbuf.f_type, fstype); *error_code = MPI_SUCCESS; return; # endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif /*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/ #ifdef ROMIO_LUSTRE #define LL_SUPER_MAGIC 0x0BD00BD0 if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } # endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
static void scaleable_stat(ADIO_File fd) { struct stat64 bg_stat; struct statfs bg_statfs; int rank, rc; char * dir; long buf[2]; MPI_Comm_rank(fd->comm, &rank); if (rank == fd->hints->ranklist[0]) { /* Get the (real) underlying file system block size */ rc = stat64(fd->filename, &bg_stat); if (rc >= 0) { buf[0] = bg_stat.st_blksize; DBGV_FPRINTF(stderr,"Successful stat '%s'. Blocksize=%ld\n", fd->filename,bg_stat.st_blksize); } else { DBGV_FPRINTF(stderr,"Stat '%s' failed with rc=%d, errno=%d\n", fd->filename,rc,errno); } /* Get the (real) underlying file system type so we can * plan our fsync scaling strategy */ rc = statfs(fd->filename,&bg_statfs); if (rc >= 0) { DBGV_FPRINTF(stderr,"Successful statfs '%s'. Magic number=%#lX\n", fd->filename,bg_statfs.f_type); buf[1] = bg_statfs.f_type; } else { DBGV_FPRINTF(stderr,"Statfs '%s' failed with rc=%d, errno=%d\n", fd->filename,rc,errno); ADIO_FileSysType_parentdir(fd->filename, &dir); rc = statfs(dir,&bg_statfs); if (rc >= 0) { DBGV_FPRINTF(stderr,"Successful statfs '%s'. Magic number=%#lX\n",dir,bg_statfs.f_type); buf[1] = bg_statfs.f_type; } else { /* Hmm. Guess we'll assume the worst-case, that it's not GPFS * or BGLOCKLESSMPIO_F_TYPE (default PVFS2) below */ buf[1] = -1; /* bogus magic number */ DBGV_FPRINTF(stderr,"Statfs '%s' failed with rc=%d, errno=%d\n",dir,rc,errno); } free(dir); } } /* now we can broadcast the stat/statfs data to everyone else */ if (fd->comm != MPI_COMM_SELF) { /* if indep open, there's no one to talk to*/ if (fd->agg_comm != MPI_COMM_NULL) /* deferred open: only a subset of processes participate */ MPI_Bcast(buf, 2, MPI_LONG, fd->hints->ranklist[0], fd->agg_comm); else MPI_Bcast(buf, 2, MPI_LONG, fd->hints->ranklist[0], fd->comm); } bg_stat.st_blksize = buf[0]; bg_statfs.f_type = buf[1]; /* data from stat64 */ /* store the blksize in the file system specific storage */ ((ADIOI_BG_fs*)fd->fs_ptr)->blksize = bg_stat.st_blksize; /* data from statfs */ if ((bg_statfs.f_type == GPFS_SUPER_MAGIC) || (bg_statfs.f_type == bglocklessmpio_f_type)) { ((ADIOI_BG_fs*)fd->fs_ptr)->fsync_aggr = ADIOI_BG_FSYNC_AGGREGATION_ENABLED; /* Only one rank is an "fsync aggregator" because only one * fsync is needed */ if (rank == fd->hints->ranklist[0]) { ((ADIOI_BG_fs*)fd->fs_ptr)->fsync_aggr |= ADIOI_BG_FSYNC_AGGREGATOR; DBG_FPRINTF(stderr,"fsync aggregator %d\n",rank); } else ; /* aggregation enabled but this rank is not an aggregator*/ } else ; /* Other filesystems default to no fsync aggregation */ }