root/test/util/opal_path_nfs.c

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

DEFINITIONS

This source file includes following definitions.
  1. main
  2. main
  3. test
  4. get_mounts

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2005 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2010      Oak Ridge National Laboratory.
  14  *                         All rights reserved.
  15  * Copyright (c) 2010-2017 Cisco Systems, Inc.  All rights reserved
  16  * Copyright (c) 2010      IBM Corporation.  All rights reserved.
  17  * Copyright (c) 2014      Los Alamos National Security, LLC. All rights
  18  *                         reserved.
  19  * Copyright (c) 2018      Research Organization for Information Science
  20  *                         and Technology (RIST). All rights reserved.
  21  * Copyright (c) 2018      Amazon.com, Inc. or its affiliates.  All Rights reserved.
  22  * $COPYRIGHT$
  23  *
  24  * Additional copyrights may follow
  25  *
  26  * $HEADER$
  27  */
  28 
  29 #include "opal_config.h"
  30 
  31 #include <stdio.h>
  32 #include <string.h>
  33 #include <stdlib.h>
  34 #include <dirent.h>
  35 
  36 #include <sys/param.h>
  37 #ifdef HAVE_SYS_MOUNT_H
  38 #include <sys/mount.h>
  39 #endif
  40 #ifdef HAVE_SYS_STATFS_H
  41 #include <sys/statfs.h>
  42 #endif
  43 #ifdef HAVE_SYS_VFS_H
  44 #include <sys/vfs.h>
  45 #endif
  46 
  47 #include "support.h"
  48 #include "opal/util/path.h"
  49 #include "opal/util/output.h"
  50 #include "opal/util/printf.h"
  51 
  52 #define DEBUG
  53 
  54 /*
  55  * On Linux, if this test is run with no command line params, it will
  56  * run "mount" and analyze the output.  It will slurp up all mount
  57  * points and figure out if they are network mounts or not.  Then it
  58  * will send each of the mount points through opal_path_nfs() and
  59  * compare the answer it gets to the answer it slurped from the output
  60  * of "mount".
  61  *
  62  * On all platforms, if you provide one or more command line options,
  63  * each command line option is given to opal_path_nfs() and the result
  64  * is sent to stdout.
  65  */
  66 
  67 #if !defined(__linux__)
  68 int main(int argc, char* argv[])
  69 {
  70     if (argc > 1) {
  71         int i;
  72 
  73         printf("Interactive opal_path_nfs() test:\n");
  74         for (i = 1; i < argc; i++) {
  75             printf ("Is dir[%d]:%s one of the detected network file systems? %s\n",
  76                     i, argv[i], opal_path_nfs (argv[i], NULL) ? "Yes": "No");
  77         }
  78 
  79         return 0;
  80     }
  81 
  82     printf("No filename was given; nothing to do\n");
  83     return 77;
  84 }
  85 
  86 #else /* __linux__ */
  87 
  88 static void test(char* file, bool expect);
  89 static void get_mounts (int * num_dirs, char ** dirs[], bool ** nfs);
  90 
  91 
  92 int main(int argc, char* argv[])
  93 {
  94     int num_dirs;
  95     char ** dirs;
  96     bool * nfs;
  97 
  98     test_init("opal_path_nfs()");
  99 #ifdef DEBUG
 100     printf ("Test usage: ./opal_path_nfs [DIR]\n");
 101     printf ("On Linux interprets output from mount(8) to check for nfs and verify opal_path_nfs()\n");
 102     printf ("Additionally, you may specify multiple DIR on the cmd-line, of which you the output\n");
 103 #endif
 104 
 105     if (1 < argc) {
 106         int i;
 107         for (i = 1; i < argc; i++)
 108             printf ("Is dir[%d]:%s one of the detected network file systems? %s\n",
 109                     i, argv[i], opal_path_nfs (argv[i], NULL) ? "Yes": "No");
 110     }
 111 
 112     get_mounts (&num_dirs, &dirs, &nfs);
 113     while (num_dirs--) {
 114         test (dirs[num_dirs], nfs[num_dirs]);
 115     }
 116 
 117     /* All done */
 118     return test_finalize();
 119 }
 120 
 121 
 122 void test(char* file, bool expect)
 123 {
 124 #ifdef DEBUG
 125     printf ("test(): file:%s bool:%d\n",
 126             file, expect);
 127 #endif
 128     if (expect == opal_path_nfs (file, NULL)) {
 129         test_success();
 130     } else {
 131         char * msg;
 132         opal_asprintf(&msg, "Mismatch: input \"%s\", expected:%d got:%d\n",
 133                  file, expect, !expect);
 134         test_failure(msg);
 135         free(msg);
 136     }
 137 }
 138 
 139 void get_mounts (int * num_dirs, char ** dirs[], bool * nfs[])
 140 {
 141 #define SIZE 1024
 142     char * cmd = "mount | cut -f3,5 -d' ' > opal_path_nfs.out";
 143     int rc;
 144     int i;
 145     FILE * file;
 146     char ** dirs_tmp;
 147     bool * nfs_tmp;
 148     char buffer[SIZE];
 149     struct statfs mystatfs;
 150 
 151     rc = system (cmd);
 152 
 153     if (-1 == rc) {
 154         *num_dirs = 0;
 155         **dirs = NULL;
 156         *nfs = NULL;
 157     }
 158 
 159     /* First, count how many mount points there are.  Previous
 160        versions of this test tried to have a (large) constant-sized
 161        array for the mount points, but periodically it would break
 162        because we would run this test on a system with a larger number
 163        of mount points than the array.  So just count and make sure to
 164        have an array large enough. */
 165     file = fopen("opal_path_nfs.out", "r");
 166     int count = 0;
 167     while (NULL != fgets (buffer, SIZE, file)) {
 168         ++count;
 169     }
 170     printf("Found %d mounts\n", count);
 171 
 172     // Add one more so we can have a NULL entry at the end
 173     ++count;
 174 
 175     dirs_tmp = (char**) calloc (count, sizeof(char*));
 176     nfs_tmp = (bool*) calloc (count, sizeof(bool));
 177 
 178     i = 0;
 179     rc = 4711;
 180     rewind(file);
 181     // i should never be more than count, but be safe anyway.
 182     while (i < count && NULL != fgets (buffer, SIZE, file)) {
 183         int mount_known;
 184         char fs[MAXNAMLEN];
 185 
 186         if (!dirs_tmp[i]) {
 187             dirs_tmp[i] = malloc (MAXNAMLEN);
 188         }
 189 
 190         if (2 != (rc = sscanf (buffer, "%s %s\n", dirs_tmp[i], fs))) {
 191             goto out;
 192         }
 193 
 194         /*
 195          * rpc_pipefs is a FS mounted on /var/lib/nfs/rpc_pipefs for NFS4
 196          * Cannot distinguish it from NFS in opal_path_nfs, therefore just
 197          * disregard it, as it is NOT an parallel filesystem...
 198          */
 199         if (0 == strcasecmp (fs, "rpc_pipefs")) {
 200             continue;
 201         }
 202 
 203         /* Per https://svn.open-mpi.org/trac/ompi/ticket/4767, Linux
 204            lies about fuse filesystems.  Skip them. */
 205         if (0 == strncasecmp(fs, "fuse.", 5)) {
 206             continue;
 207         }
 208 
 209         /* If we get an fs type of "none", skip it (e.g.,
 210            http://www.open-mpi.org/community/lists/devel/2012/09/11493.php) */
 211         if (0 == strcasecmp(fs, "none")) {
 212             continue;
 213         }
 214 
 215         /* If we can not stat the fs, skip it */
 216         if (statfs (dirs_tmp[i], &mystatfs)) {
 217             continue;
 218         }
 219 
 220         /*
 221          * Later mounts override earlier mounts
 222          * (e.g. nfs-mount of /, vs. initial rootfs-mount of /).
 223          */
 224         for (mount_known = 0; mount_known < i; mount_known++) {
 225             /* If we know this mount-point, then exit early */
 226             if (0 == strcasecmp (dirs_tmp[mount_known], dirs_tmp[i])) {
 227 #ifdef DEBUG
 228                 printf ("get_mounts: already know dir[%d]:%s\n",
 229                         mount_known, dirs_tmp[mount_known]);
 230 #endif
 231                 break;
 232             }
 233         }
 234 
 235         nfs_tmp[mount_known] = false;
 236         if (0 == strcasecmp (fs, "nfs") ||
 237             0 == strcasecmp (fs, "nfs4") ||
 238             0 == strcasecmp (fs, "lustre") ||
 239             0 == strcasecmp (fs, "panfs") ||
 240             0 == strcasecmp (fs, "gpfs"))
 241             nfs_tmp[mount_known] = true;
 242 #ifdef DEBUG
 243         printf ("get_mounts: dirs[%d]:%s fs:%s nfs:%s\n",
 244                 mount_known, dirs_tmp[mount_known],
 245                 fs, nfs_tmp[mount_known] ? "Yes" : "No");
 246 #endif
 247 
 248         if (mount_known >= i)
 249             i++;
 250 
 251     }
 252 out:
 253     *num_dirs = i;
 254     *dirs = dirs_tmp;
 255     *nfs = nfs_tmp;
 256 }
 257 
 258 #endif /* __linux__ */

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