1
1

Make the use of statfs()/statvfs() be more robust.

As noted by Paul Hargrove, the #if's surrounding the use of statfs()
and statvfs() in opal/util/path.c have apparently gotten stale (e.g.,
modern flavors of *BSD OSs no longer define __BSD).  Changes:

 * Add statfs and statvfs to the AC_CHECK_FUNCS in configure.ac
 * Add a sanity check to ensure that we have at least one of statfs()
   or statvfs().  Add a similar sanity check in opal/util/path.c, just
   as defensive programming.
 * Use AC_CHECK_MEMBERS in configure.ac to check for specific struct
   statfs/struct statvfs members that we use in opal/util/path.c
 * In path.c, add some #includes as listed on the OS man page for
   statfs(2) (OS X 10.8.5/Mountain Lion)
 * The previous code used statvfs() on Solaris and statfs() everywhere
   else.  Attempting to replicate this with behavior-based configure
   testing led to fairly complicted if/else logic, so the new code
   uses whichever of the two are available (i.e., it might actually
   use both -- OS X 10.8.5 and RHEL 6.5 have both statfs() and
   statvfs()).  The rationale here is that we don't really care which
   of the two functions report the answer; we'll take the answer
   regardless of where it comes from.  For example, if one function
   returns a failure and the other does not, we'll use the results
   from the successful function and ignore the failed one.

This new code seems to work on OS X and Linux.  We'll have to see what
happens with MTT and future Paul Hargrove testing...

cmr=v1.7.4:reviewer=ompi-rm1.7:subject=Make statfs/statvfs more robust

This commit was SVN r30198.
Этот коммит содержится в:
Jeff Squyres 2014-01-09 21:28:52 +00:00
родитель 24e990e747
Коммит c67c8e8187
2 изменённых файлов: 111 добавлений и 37 удалений

Просмотреть файл

@ -10,7 +10,7 @@
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006-2013 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2006-2014 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2006-2008 Sun Microsystems, Inc. All rights reserved.
# Copyright (c) 2006-2011 Los Alamos National Security, LLC. All rights
# reserved.
@ -748,6 +748,45 @@ AC_CHECK_MEMBERS([struct dirent.d_type], [], [], [
AC_CHECK_MEMBERS([siginfo_t.si_fd],,,[#include <signal.h>])
AC_CHECK_MEMBERS([siginfo_t.si_band],,,[#include <signal.h>])
#
# Checks for struct member names in struct statfs
#
AC_CHECK_MEMBERS([struct statfs.f_type], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#ifdef HAVE_STS_STATFS_H
#include <sys/statfs.h>
#endif
])
AC_CHECK_MEMBERS([struct statfs.f_fstypename], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#ifdef HAVE_STS_STATFS_H
#include <sys/statfs.h>
#endif
])
#
# Checks for struct member names in struct statvfs
#
AC_CHECK_MEMBERS([struct statvfs.f_basetype], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_STS_STATVFS_H
#include <sys/statvfs.h>
#endif
])
# checkpoint results
AC_CACHE_SAVE
@ -775,7 +814,13 @@ OMPI_CHECK_FUNC_LIB([dirname], [gen])
# Darwin doesn't need -lm, as it's a symlink to libSystem.dylib
OMPI_CHECK_FUNC_LIB([ceil], [m])
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty getpwuid fork waitpid execve pipe ptsname setsid mmap tcgetpgrp posix_memalign strsignal sysconf syslog vsyslog regcmp regexec regfree _NSGetEnviron socketpair strncpy_s _strdup usleep mkfifo dbopen dbm_open])
AC_CHECK_FUNCS([asprintf snprintf vasprintf vsnprintf openpty isatty getpwuid fork waitpid execve pipe ptsname setsid mmap tcgetpgrp posix_memalign strsignal sysconf syslog vsyslog regcmp regexec regfree _NSGetEnviron socketpair strncpy_s _strdup usleep mkfifo dbopen dbm_open statfs statvfs])
# Sanity check: ensure that we got at least one of statfs or statvfs.
if test $ac_cv_func_statfs = no -a $ac_cv_func_statvfs = no; then
AC_MSG_WARN([neither statfs() and statvfs() were found])
AC_MSG_ERROR([Cannot continue])
fi
# On some hosts, htonl is a define, so the AC_CHECK_FUNC will get
# confused. On others, it's in the standard library, but stubbed with

Просмотреть файл

@ -9,7 +9,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010 IBM Corporation. All rights reserved.
* Copyright (c) 2012-2013 Los Alamos National Security, LLC.
* All rights reserved.
@ -31,6 +31,9 @@
#ifdef HAVE_SHLWAPI_H
#include <shlwapi.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
@ -46,6 +49,9 @@
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
@ -56,6 +62,13 @@
#include "opal/util/os_path.h"
#include "opal/util/argv.h"
/*
* Sanity check to ensure we have either statfs or statvfs
*/
#if !defined(HAVE_STATFS) && !defined(HAVE_STATVFS)
#error Must have either statfs() or statvfs()
#endif
static void path_env_load(char *path, int *pargc, char ***pargv);
static char *list_env_get(char *var, char **list);
@ -428,13 +441,14 @@ char* opal_find_absolute_path( char* app_name )
bool opal_path_nfs(char *fname)
{
int i;
int rc;
int fsrc, vfsrc;
int trials;
char * file = strdup (fname);
#if defined(__SVR4) && defined(__sun)
struct statvfs buf;
#elif defined(__linux__) || defined (__BSD) || (defined(__APPLE__) && defined(__MACH__))
struct statfs buf;
#if defined(HAVE_STATFS)
struct statfs fsbuf;
#endif
#if defined(HAVE_STATVFS)
struct statvfs vfsbuf;
#endif
/*
* Be sure to update the test (test/util/opal_path_nfs.c)
@ -448,26 +462,31 @@ bool opal_path_nfs(char *fname)
{LL_SUPER_MAGIC, MASK4, "lustre"},
{NFS_SUPER_MAGIC, MASK2, "nfs"},
{PAN_KERNEL_FS_CLIENT_SUPER_MAGIC, MASK4, "panfs"},
{GPFS_SUPER_MAGIC, MASK4, "gpfs"}
{GPFS_SUPER_MAGIC, MASK4, "gpfs"}
};
#define FS_TYPES_NUM (int)(sizeof (fs_types)/sizeof (fs_types[0]))
/*
* First, get the OS-dependent struct stat(v)fs buf
* This may return the ESTALE error on NFS, if the underlying file/path has changed
* First, get the OS-dependent struct stat(v)fs buf. This may
* return the ESTALE error on NFS, if the underlying file/path has
* changed.
*/
again:
#if defined(HAVE_STATFS)
trials = 5;
do {
#if defined(__SVR4) && defined(__sun)
rc = statvfs (file, &buf);
#elif defined(__linux__) || defined (__BSD) || (defined(__APPLE__) && defined(__MACH__))
rc = statfs (file, &buf);
fsrc = statfs(file, &fsbuf);
} while (-1 == fsrc && ESTALE == errno && (0 < --trials));
#endif
#if defined(HAVE_STATVFS)
trials = 5;
do {
vfsrc = statvfs(file, &vfsbuf);
} while (-1 == vfsrc && ESTALE == errno && (0 < --trials));
#endif
} while (-1 == rc && ESTALE == errno && (0 < --trials));
/* In case some error with the current filename, try the directory */
if (-1 == rc) {
if (-1 == fsrc && -1 == vfsrc) {
char * last_sep;
OPAL_OUTPUT_VERBOSE((10, 0, "opal_path_nfs: stat(v)fs on file:%s failed errno:%d directory:%s\n",
@ -486,23 +505,33 @@ again:
}
/* Next, extract the magic value */
#if defined(__SVR4) && defined(__sun)
for (i = 0; i < FS_TYPES_NUM; i++)
if (0 == strncasecmp (fs_types[i].f_fsname, buf.f_basetype, FSTYPSZ))
for (i = 0; i < FS_TYPES_NUM; i++) {
#if defined(HAVE_STATFS)
/* These are uses of struct statfs */
# if defined(HAVE_STRUCT_STATFS_F_FSNAME)
if (0 == fsrc &&
0 == strncasecmp(fs_types[i].f_fsname, fsbuf.f_fstypename,
sizeof(fsbuf.f_fstypename))) {
goto found;
#elif (defined(__APPLE__) && defined(__MACH__))
for (i = 0; i < FS_TYPES_NUM; i++)
if (0 == strncasecmp (fs_types[i].f_fsname, buf.f_fstypename, MFSTYPENAMELEN))
goto found;
#elif defined(__BSD)
for (i = 0; i < FS_TYPES_NUM; i++)
if (0 == strncasecmp (fs_types[i].f_fsname, buf.f_fstypename, MFSNAMELEN))
goto found;
#elif defined(__linux__)
for (i = 0; i < FS_TYPES_NUM; i++)
if (fs_types[i].f_fsid == (buf.f_type & fs_types[i].f_mask))
}
# endif
# if defined(HAVE_STRUCT_STATFS_F_TYPE)
if (0 == fsrc &&
fs_types[i].f_fsid == (fsbuf.f_type & fs_types[i].f_mask)) {
goto found;
}
# endif
#endif
#if defined(HAVE_STATVFS)
/* This is a use of struct statvfs */
# if defined(HAVE_STRUCT_STATVFS_F_BASETYPE) && defined(FSTYPSZ)
if (0 == vfsrc &&
0 == strncasecmp(fs_types[i].f_fsname, vfsbuf.f_basetype, FSTYPSZ)) {
goto found;
}
# endif
#endif
}
free (file);
return false;
@ -523,10 +552,10 @@ opal_path_df(const char *path,
int rc = -1;
int trials = 5;
int err = 0;
#if defined(__SVR4) && defined(__sun)
struct statvfs buf;
#else
#if defined(HAVE_STATFS)
struct statfs buf;
#elif defined(HAVE_STATVFS)
struct statvfs buf;
#endif
if (NULL == path || NULL == out_avail) {
@ -535,10 +564,10 @@ opal_path_df(const char *path,
*out_avail = 0;
do {
#if defined(__SVR4) && defined(__sun)
rc = statvfs(path, &buf);
#else
#if defined(HAVE_STATFS)
rc = statfs(path, &buf);
#elif defined(HAVE_STATVFS)
rc = statvfs(path, &buf);
#endif
err = errno;
} while (-1 == rc && ESTALE == err && (--trials > 0));